静音推送未传递到iOS 11上的应用程序


168

我注意到在iOS 11 beta 2上,application:didReceiveRemoteNotification:fetchCompletionHandler无论应用程序的状态(背景/前景)如何,静默通知都不会传递到。

我实现了该UIApplicationDelegete方法,application:didReceiveRemoteNotification:fetchCompletionHandler并发送以下静默推送

{  
  "aps": {  
    "content-available": 1  
  },  
  "mydata": {  
    "foo": "bar"  
  }  
} 

但在iOS 11上未调用委托方法。

它在其他版本的iOS上也能正常工作,而文档部分“ 配置静默通知”中并未提及需要执行其他任何操作。

这是iOS 11中的错误,还是我错过了iOS 11中的新功能?

请注意,我并不是在谈论或使用该UserNotification框架,而该框架不需要发送静默推送。

这是一个说明问题的示例项目(您必须设置自己的bundle id)

当您午餐示例项目并将上述有效负载发送到应用程序时,您可以使用macOS控制台查看推送是否正确传递到设备,而不是正确传递给应用程序。

更新10.08

看来该行为是随机的。有时在重新启动设备后,有效负载会正确交付,但一段时间后它将停止工作。

如下面的屏幕快照所示,标记为1的推送仅发送给设备,推送2(在设备重启后)也传递给应用程序。

在此处输入图片说明

更新14.08-iOS 11 Beta 6

仍然是相同的行为。以下是应该起作用但不起作用的另一件事。当应用程序的方案设置为“等待启动可执行文件”时,应该以静默方式唤醒应用程序并在后台启动它。

在此处输入图片说明

更新21.08-iOS 11 Beta 7

仍然是相同的行为,并且错误报告中没有来自Apple的更新。

更新29.08-iOS 11 Beta 8

还是一样的问题。现在使用的重现步骤如下:

  • 在Xcode项目方案中,选择“等待可执行文件启动”
  • 在中添加断点 didReceiveRemoteNotification: fetchCompletionHandler
  • 在设备上启动应用
  • 发送以上无声推送

预期:该应用程序从暂停状态进入后台,并且didReceiveRemoteNotification: fetchCompletionHandler被称为

实际:什么也没发生

更新06.09-iOS 11 Beta 10

我仍然有同样的越野车行为。苹果的票证已更新为以下答案:

Apple开发人员关系2017年9月6日,下午10:42工程部已就此问题提供了以下反馈:

我们能够使示例应用程序运行并测试行为。按说明进行测试时,我们没有发现任何问题。

当应用程序在后台运行时,不能保证推送会到达该应用程序,并且此处的日志表明我们认为该应用程序的使用率不足以启动它。

我们确实看到我们在情况良好时不时地进行推送。

我们认为这是正确的行为。

更新11.09

我的Apple错误报告已关闭,并被标记为重复33278611打开

更新13.09-iOS 11 GM

感谢kam800的评论(见下文),我进行了更多测试,并提出了以下观察结果:

iOS 11 dasd DuetActivitySchedulerDaemon中似乎有一个新的守护程序,它要么完全丢弃数据推送,要么延迟数据推送交付:

交货推迟

控制台日志

default 13:11:47.177547 +0200   dasd    DuetActivitySchedulerDaemon CANCELED: com.apple.pushLaunch.net.tequilaapps.daylight:C03A65 <private>!   lifecycle   com.apple.duetactivityscheduler
default 13:11:47.178186 +0200   dasd    DuetActivitySchedulerDaemon Removing a launch request for application <private> by activity <private>   default com.apple.duetactivityscheduler
default 12:49:04.426256 +0200   dasd    DuetActivitySchedulerDaemon Advancing start date for <private> by 6.5 minutes to Wed Sep 13 12:55:31 2017   default com.apple.duetactivityscheduler
default 13:21:40.593012 +0200   dasd    DuetActivitySchedulerDaemon Activity <private>: Optimal Score 0.6144 at <private> (Valid Until: <private>)  scoring com.apple.duetactivityscheduler
default 13:21:40.594528 +0200   dasd    DuetActivitySchedulerDaemon Setting timer (isWaking=1, activityRequiresWaking=0) between <private> and <private> for <private>  default com.apple.duetactivityscheduler

交货延迟

  • 推迟数据推送交付并启动应用程序时,仅在达到交付日期(可能是未来几分钟)的情况下才交付数据推送。这完全破坏了使用数据推送来保持新应用程序内容为下一次启动做好准备的目的。我在这里再次引用Apple的文档:

“无声通知可以帮助您确保应用程序即使在未运行时也保持最新状态,从而改善了用户体验。”

  • 两次数据推送发送到已暂停的应用程序时,它们会被iOS 11推迟,而不是直接唤醒应用程序。到达交付时间后,交付最后的数据推送!先前的推送将丢失,并且不会通过委托方法传递,从而导致数据丢失。

交货已取消

控制台日志

default 13:35:05.347078 +0200   dasd    DuetActivitySchedulerDaemon com.apple.pushLaunch.net.tequilaapps.daylight:C03A65:[
    {name: ApplicationPolicy, policyWeight: 50.000, response: {Decision: Must Not Proceed, Score: 0.00}}
 ], FinalDecision: Must Not Proceed}    scoring com.apple.duetactivityscheduler

取消交货问题

好吧,在这种情况下,数据推送完全丢失,并且在iOS 10上正确交付时也从未在iOS 11上交付过。

更新19.09-iOS 11 GM

我还注意到,当应用程序位于前台并且通知未传递到应用程序时,我在控制台中看到以下日志:

default 08:28:49.354824 +0200   apsd    apsd    <private>: Received message for enabled topic '<private>' onInterface: NonCellular with payload '<private>' with priority 10 for device token: NO   courier-oversized   com.apple.apsd

fault   08:33:18.128209 +0200   dasd    Foundation  <NSXPCConnection: 0x151eee460> connection from pid 55: Exception caught during decoding of received message, dropping incoming message.
Exception: Exception while decoding argument 0 (#2 of invocation):
Exception: value for key 'NS.objects' was of unexpected class 'NSNull'. Allowed classes are '{(
    NSArray,
    NSData,
    NSString,
    NSNumber,
    NSDictionary,
    NSUUID,
    _DASActivity,
    NSSet,
    _DASFileProtection,
    NSDate,
    NWParameters,
    NWEndpoint
)}'.    general com.apple.foundation.xpc

1
在Beta 8中仍然没有修复,当我在控制台中查看时,我看到以下错误:来自pid 58的<NSXPCConnection:0x123f43620>连接:解码接收到的消息时,捕获了异常,丢弃了传入消息。异常:解码参数0(调用#2)时发生异常:异常:键'NS.objects'的值属于意外类'NSNull'。允许的类为“ {{NWParameters,NWEndpoint,NSArray,NSData,NSString,NSNumber,NSDictionary,NSUUID,_DASActivity,NSSet,_DASFileProtection,NSDate}}”。
托马斯·爱因华勒

2
我在iOS 11上获得了相同的结果(不是之前),如果我使用进行推送"content-available": 1,并且应用程序处于前台,则不会触发回调。
GoRoS

4
在使用新的iOS11.1 beta 1测试之后,看来此问题现已修复,并且可以像以前在iOS 10上正常工作
Lee

3
Whatsapp似乎也遇到过类似的问题whatsappen.com/news/5465/…关于用户“习惯性地强制关闭其应用程序”的东西,这对大多数开发人员来说都是如此……
toxaq

3
与公开发布的11.1完全相同。如果您正在使用无声推送并且您的应用程序处于前台,那么即使设备已插入电源,也不要期望它们取决于几件事,但主要取决于电池电量。
Gruntcakes '17

Answers:


31

因此,iOS 11.1 beta 1的发行说明说

iOS 11.1 beta 1刚刚发布,他们提到:“已解决的通知•静默推送通知的处理频率更高。(33278611)

我做了一些测试,看来确实是固定的:

暂停状态

当我以暂停模式启动该应用并发送静默推送时,该应用将恢复为后台, didReceiveRemoteNotification:fetchCompletionHandler调用委托。

前景状态

以同样的方式,当应用程序处于前台并且发送了静默推送时,似乎已按预期调用了该委托。这是随机没有在以前的iOS版本11工作,所以更多的测试后,我会证实这一点。


3
在我最初的测试中,我认为它是固定的。它工作了一段时间。但是经过一些严格的测试之后,事情开始逐渐变得复杂起来。突然,即使在应用程序处于前台的情况下,它也不再为每次无声推送而调用委托。显然,由于缺少“ energyBudget”,这个新的“ duet”系统阻止了我的应用程序的代表被调用。因此,不幸的是,仍然没有解决。
阿布拉斯

令人难以置信::
Thomas Einwaller

我的经验与上述艾布拉斯相同。工作了一会儿,然后崩溃了,经理不再被叫-这很烂,

经过更多测试后,我找到了使设备再次接收通知的方法。将其接通电源。将设备接通电源后,设备将再次开始接收所有远程通知。如果断开连接,它将停止。这没有任何意义,因为在我所有的测试中,该应用程序都处于前台。并且前景看好的应用程序可以接收到远程通知。
艾布拉斯(Abras)

对我来说,即使在不连接电源的情况下进行蜂窝连接时,它们也都可以正常工作。仅当我将设备设置为省电模式时,即使在前台,我也不会得到推动。但是,这件事情我会理解的

18

我只是想在这里加2美分,因为我也受到这个问题的打击,而且我注意到Apple已关闭有关此问题的多个雷达,称它们无法复制。我发现一个有趣的事情是,如果将应用程序附加到调试器时使其处于后台,则推送将被传递。

如果我杀死了调试器,请拔下电话,启动应用程序,然后发送无声推送有效负载,但我看不到应用程序被唤醒。我确实在控制台日志中看到,系统取消了将负载发送到我的应用程序的操作。

我提交了一个雷达,该雷达带有一个可重现该问题的小型示例应用程序。我还明确指出,在我的票证上工作的人一定不能运行调试器附带的应用程序才能重现该问题。这是链接:https : //bugreport.apple.com/web/?problemID=34461063

希望这将在此问题上取得一些进展。


2
感谢您的报告。顺便说一句,连接苹果的错误不会在这里帮助,因为它们是私有的,只能记者和苹果可以看到他们

我希望看到更多人使用openradar.appspot.com,以便我们可以跟踪其他人的雷达
Thomas Einwaller

apple @bill您的错误报告有任何更新吗?
MagicFlow

我还没有收到Apple提供的任何更新,但是我们已经安装了iOS 11.1 beta版,看来问题已解决。
比尔·杜奈

是的,我们在iOS 11.2.6中也面临相同的问题,是否有任何解决方案或更新?
Gopik

14

看起来像是iOS 11的新行为。iOS11 beta 10提供了有关此问题的一些描述性日志:

default 23:18:51.806011 +0200   dasd    com.apple.pushLaunch.com.acme.Acme:F7E7D0:[
    {name: ApplicationPolicy, policyWeight: 50.000, response: {Decision: Can Proceed, Score: 0.50}}
    {name: BatteryLevelPolicy, policyWeight: 1.000, response: {Decision: Can Proceed, Score: 0.87, Rationale: [{batteryLevel == 62}]}}
    {name: DeviceActivityPolicy, policyWeight: 5.000, response: {Decision: Can Proceed, Score: 0.20}}
 ] sumScores:52.279483, denominator:81.410000, FinalDecision: Can Proceed FinalScore: 0.642175}
default 23:18:51.806386 +0200   dasd    'com.apple.pushLaunch.com.acme.Acme:F7E7D0' has compatibility score of 1.000000 with 'com.apple.CFNetwork-cc-111-79:E7272D'. Relaxing scores.
default 23:18:51.806855 +0200   dasd    'com.apple.pushLaunch.com.acme.Acme:F7E7D0' CurrentScore: 0.642175, ThresholdScore: 0.738454 DecisionToRun:0

看起来每个无声推送都已传递到iOS,但是dasd守护程序使用了几个策略来决定是否应将无声推送传递给应用程序(例如电池电量)。昨天晚上我设法进行了一次无声推送,但是当时我的iPhone已连接到充电器-BatteryLevelPolicy评分可能足够高,可以接受一次无声推送。

Apple没有提供有关此iOS端行为的官方信息,只有有关服务器端限制的信息:

静默通知并不意味着让您的应用程序在后台保持清醒,也不是为了进行高优先级更新。APN将静默通知视为低优先级,如果总数过多,则它们可能会完全限制其发送。实际限制是动态的,可以根据条件而变化,但请尝试每小时发送的通知不超过几个。

我指责他们改变了这种行为,因为那会修复我的应用程序:)另一方面,这种变化很好–其中许多原因使得iPhone电池的使用寿命比Android手机更长。


1
是的,推送已传递到设备,但未传递到应用程序。那就是我在原始帖子中写的。“静默通知并不意味着让您的应用在后台保持清醒”,只要它们“有时”交付就可以。最大的问题是,静音通知永远不会在后台运行时传递到iOS 11中的应用程序。这完全破坏了数据推送的全部目的。

是的,您已经写道,我只是想提供有关这些新推送策略的完整说明。我引用Apple文档来表明他们已经警告过推送不确定性。正如我写的:“昨天晚上我设法获得了一个无声的推送”(在我所指的应用中),该应用处于后台。但是在今天–我的应用程序没有收到推送:(我认为Apple会放松RC版本的这些推送策略。另一方面,它们可以恢复原始的推送行为–他们已经摆脱了仅在beta版本(例如10.3钥匙串自动删除)
。– kam800

收到推送消息并暂停应用程序时,我会看到类似的日志。dasd 然后,该过程记录下来default 10:17:42.994236 +0200 dasd DuetActivitySchedulerDaemon Advancing start date for <private> by 6.3 minutes to Wed Sep 13 10:24:03 2017。无声的推送似乎在那个时候完成了。

已经开始使用iOS 11 GM进行测试,仍然看到怪异的行为,例如 com.apple.fetch.com.troii.timriphone:F613DA:[ {name: ApplicationPolicy, policyWeight: 50.000, response: {Decision: Must Not Proceed, Score: 0.00}} ], FinalDecision: Must Not Proceed}
Thomas Einwaller

1
另外-我设法通过发送带有一些存根通知的非静默推送来解决我的应用,并使用Notification Service Extension将通知填充了正确的内容。
kam800

9

iOS 11.1 Beta发行说明包括:已解决的通知静默推送通知的处理频率更高。(33278611)


7

iOS 11.1 Beta 2还包含

Notifications
Resolved Issues
 Silent push notifications are processed more frequently. (33278611)

发行说明中的​​内容-现在将对其进行测试。

更新-11.10.2017-iOS 11.1 Beta 2

在“现实场景”中使用我们的应用程序2天后,此版本的iOS似乎有了实质性的改进。我开始谨慎地认为这是固定的。


1
我测试了不同的方案:它在前台和后台状态下工作。不幸的是,如果该应用程序被用户终止,则无法使用。终止后,只要用户没有再次主动启动该应用程序,该设备就不会收到任何静默推送。你有同样的经历吗?
AlexWoe89年

现在它可以工作了……经过大约“停机”时间。5到10分钟内,静默通知正在按预期方式工作...非常抱歉。评论:)
AlexWoe89 '10

1
当用户终止应用程序时,静默推送从不起作用-请参阅developer.apple.com/documentation/uikit/uiapplicationdelegate/… “但是,如果用户强制退出,系统不会自动启动您的应用程序。”
Thomas Einwaller

1
我看到iOS11.1 beta 3的运行方式与iOS10相似,并且比iOS11.1 beta 2更好。

1
@Olecramoak对我来说iOS11.1 beta 4和iOS 10一样工作
。– AlexWoe89

7

苹果开发人员关系部刚刚在我的雷达中添加了一条评论:

我们认为此问题已在最新的iOS 11.2 beta中得到解决。

请测试最新的iOS Beta。如果仍有问题,请使用任何相关日志或信息来更新错误报告,以帮助我们进行调查。

https://developer.apple.com/download/

当前正在安装iOS 11.2 beta-将测试静默推送行为


那么这是否意味着iOS 11.1 GM无法解决该问题?:(
Olecramoak

很高兴听到,我们什么时候才能真正期待iOS11.1的正式发布?
AlexWoe89年

保持联系状态,当前无法安装我的应用程序,因为没有适用于11.2的Xcode。(并且我从设备上删除了该应用)
Rool Paap '17

3

我的应用遇到类似的问题,直到iOS 10出现推送通知, application:didReceiveRemoteNotification:fetchCompletionHandler正确调用,但是当更新到iOS 11时推送通知停止工作。

我的代码存在问题,即使我在推送通知有效内容中使用content-available:1和mutable-content:1,也未启用Background Fetch选项。但是直到iOS 10都运行良好。

确保您同时打开了这两个功能。

启用后台获取功能后,它现在可以工作


不,它不适用于iOS11-只需终止您的应用一次,然后它就不会唤醒您的应用。只需阅读此主题的答案和评论
AlexWoe89 '17

2
对于终止的应用程序,任何推送通知(连续或常规推送)都不会触发应用程序委托中的委托方法。多数民众赞成在默认的行为。iOS 11.0没有特殊情况。
乔治

3

iOS 11.4.1,Swift 4

我遇到了静默推送(无法从CloudKit到达)的问题,我尝试了所有人在这里提到的所有内容。然后,我决定尝试alertBody为我的CKNotificationInfo()对象设置一个空白,如下所示:

let info = CKNotificationInfo()
info.shouldSendContentAvailable = true
info.alertBody = ""

这使得推送的发送优先级更高(但是它们仍然是静默推送),而且我的设备日志中也不再出现错误,该推送被忽略。

希望对您有所帮助。:)


同样适用于CloudKit。如果没有alertBody,则需要插入设备以获取remoteNotifications。非常奇怪的行为...
powertoold

2

因此,这确实是iOS 11中的错误,现在已在iOS 11 beta 3中修复。application:didReceiveRemoteNotification:fetchCompletionHandler现在在前台或后台收到静默推送时,现在可以正确调用此错误。

更新

不,它不是固定的,并且仍在iOS beta 3和4中发生


1
其实这是不:(它仍然在IOS 11的Beta 3发生

1
苹果也重新打开了错误报告。我会让你知道

1
我没有在iOS 11 beta 4中收到静默推送。更令人担忧的是,如果应用程序不在前台,则它们有时会以常规通知的形式出现。肯定有事!
Ben Dodson

1
因此,我刚刚安装了iOS 11 beta 5,它看起来更好,并且当应用程序通过didReceiveRemoteNotification委托处于前台或后台时,静默通知会发出一段时间,然后不管我做什么,它都会再次停止工作:/同样的行为?

1
如果您同时进行测试也很酷,这让我头疼。重新启动设备后,无声推送会随机起作用或不会起作用。我更新了我原来的职位与样本项目,所以,我们都使用相同的

2

解决方法是在空字符串作为值的“标题”中添加“通知”键。这是唤醒appDelegate中的didReceive回调。


1
这似乎对我有用,也可以使用一种解决方法,使DuetActivitySchedulerDaemon允许通知唤醒应用程序,直到Apple修复该错误为止。
Joe Benton

当推送包含空标题的JSON时,我仍然在控制台上收到消息“正在忽略没有警报,声音或标志的通知...” {“ aps”:{“ alert”:{“ title”:“”}, “ content-available”:“ 1”},“ gcm.message_id”:“ 0 ... bb”}这个JSON结构对您有用吗?
Olecramoak

您不应该发送不带引号的1(可用内容的值)吗?
elkorb

这就是Google Firebase格式化Json(“ 1”)的方式,并且始终有效。只是dasd废话的iOS 11造成了问题。您能否发布一个适合您的Json示例?
Olecramoak

因此,我在iOS 11.1上观察到的是,即使设备未使用电池运行(未充电)并且电池电量不足20%(即使未激活低能耗模式),也不会传递静默推送。这不好。无声地推送iOS 11根本不可靠,几乎没有用。
Olecramoak

1

在撰写此答案时,我正面临与比尔·杜奈Bill Dunay)答案完全相同的问题。

我的要求是在应用程序处于前台状态时接收静默通知,而在应用程序处于后台/未运行时不接收任何通知。我的解决方法是这样。我不使用徽章,因此将其设置为零对我来说不是问题。

{
    "aps" : {
        "badge" : 0,
        "sound" : ""
    },
    "mydata": {  
        "foo": "bar"  
    }  
}

请注意,我故意不使用“可用内容”。导致iOS优化逻辑开始延迟/取消通知传递的设置。


1

对于某些通知,我一直遇到相同的问题(不一定是沉默的)。

查看所有更新和答案后,我可以添加两个可能有帮助的更新:

  • 我发现UIApplication.shared.isRegisteredForRemoteNotifications在收到通知时访问方法会导致应用程序停止运行,而没有向Xcode报告任何内容。收到访问该方法的通知后,检查是否正在运行某些代码。(isRegisteredForRemoteNotifications使用semaphore_wait_trap锁定UI)。

    • 我发现控制台上有一个推送通知解析错误,原因是它"title-loc-args" : [3333]不按字面意思接受3333,而是接受它作为字符串"title-loc-args" : ["3333"]。在我访问上述方法后,这使我的整个界面停滞了,仅在iOS 11上有效,它在iOS 12上有效。
  • 我还发现,使用完全相同的代码,它可以在iOS 12.0(16A5366a)上正常运行。但是在iOS 11上却正在发生。


1

在我的情况下,在服务器站点上完成工作后,使用静默通知来更新ui,因此在应用程序中包含不相关的内容很麻烦。因为我们用于静默通知的有效负载甚至包含标题和正文,所以我实现了这些方法以在活动/不活动的应用程序中获取工作通知,而不是充电并且关闭了后台应用程序刷新,甚至处于低功耗状态。

为了使此工作正常进行,我添加了委托并使用UNUserNotificationCenterDelegate协议和willPresent notification(iOS 10+)方法创建扩展,每次使用正确的有效负载触发该扩展。要在应用处于活动状态时不显示通知,只需用徽章或声音呼叫完成即可。我最终得到了这样的东西

    import UserNotifications

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
    var window: UIWindow?

    // MARK: - Lifecycle
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        UNUserNotificationCenter.current().delegate = self
        return true
    }

    //this was only method to handle notifications before
    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any],
                     fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
        //process silent notification
        completionHandler(UIBackgroundFetchResult.newData)
    }
}

extension AppDelegate : UNUserNotificationCenterDelegate {
    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        //proces notification when app is active with `notification.request.content.userInfo`
        if UIApplication.shared.applicationState == .active {
            completionHandler(.badge)
        }else {
            completionHandler(.alert)
        }
    }
}

为了在应用处于后台且无提示通知时使这些状态工作,请不要调用我的方法,我可以applicationDidBecomeActive通过以下方式直接从通知中心获取通知:

UNUserNotificationCenter.current().getDeliveredNotifications { (notifications) in
            debugLog(message: "unprocessed notification count: \(notifications.count)")
            if notifications.count > 0 {
                notifications.forEach({ (notification) in
                    DispatchQueue.main.async {
                        //handle `notification.request.content.userInfo`
                    }
                })
            }
        }

0

就我而言,iPhone设置中的“后台应用程序刷新”已关闭。因此,推送通知已发送到设备,但未发送到应用程序。启用后台应用程序刷新会在应用程序中收到静默推送。

这可能不是此问题的实际答案,以防万一有人需要检查。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.