iOS 11上的应用程序未提供无声推送
我注意到,在iOS 11 beta 2上,无论应用程序的状态如何(后台/前台),静默通知都不会发送到iOS 11上的应用程序未提供无声推送,ios,push-notification,ios11,Ios,Push Notification,Ios11,我注意到,在iOS 11 beta 2上,无论应用程序的状态如何(后台/前台),静默通知都不会发送到应用程序:didReceiveMemotentification:fetchCompletionHandler 我实现了UIApplicationDelegete方法application:didReceiveEmotentification:fetchCompletionHandler,并发送以下静默推送 { "aps": { "content-available": 1
应用程序:didReceiveMemotentification:fetchCompletionHandler
我实现了UIApplicationDelegete
方法application:didReceiveEmotentification:fetchCompletionHandler
,并发送以下静默推送
{
"aps": {
"content-available": 1
},
"mydata": {
"foo": "bar"
}
}
但在IOS11上不调用委托方法
它可以在其他版本的iOS上正常工作,文档部分没有提到其他任何操作
这是iOS 11中的一个bug还是我错过了iOS 11中的一些新功能
请注意,我不是在谈论或使用UserNotification
框架,发送静默推送不需要该框架
下面是一个示例,说明了这个问题(您必须设置自己的bundle id)
当您使用示例项目并将上述有效负载发送到应用程序时,您可以使用macOS控制台查看推送是否正确发送到设备,而不是应用程序
更新10.08
这种行为似乎是随机的。有时,在重新启动设备后,有效负载会正确传递,但过一段时间后会停止工作
正如您在下面的屏幕截图中所看到的,标记为1的推送仅发送到设备,而推送2(在设备重新启动后)也发送到应用程序
更新14.08-iOS 11 Beta 6
还是一样的行为。另一件本应有效但却无效的事情是:。当应用程序的方案设置为“等待可执行文件被启动”时,一个静默推送应该会唤醒应用程序并在后台启动它
更新21.08-iOS 11 Beta 7
仍然是同样的行为,而不是在bug报告中苹果的更新
更新29.08-iOS 11 Beta 8
还是一样的问题。我现在使用的复制步骤如下:
- 在Xcode项目方案中,选择“等待可执行文件启动”
- 在
didReceiveEmotentification:fetchCompletionHandler
- 在设备上启动应用程序
- 发送上述无声推送
DidReceiveMemoteNotification:fetchCompletionHandler
实际的:什么都没有发生
更新06.09-iOS 11 Beta 10
我仍然有同样的行为。来自苹果的票证更新为以下答案:
苹果-开发商关系2017年9月6日晚上10:42工程部
就这个问题提供了以下反馈:
我们能够让示例应用程序运行并测试其行为。我们
当我们按照描述进行测试时,没有发现任何问题
推送不保证在应用程序运行时到达应用程序
背景和这里的日志表明我们不相信该应用程序是正确的
被用来发射它
我们确实看到,在条件允许的情况下,我们会时不时地进行推送
好
我们认为这是正确的
更新11.09
我的Apple bug报告已关闭,并标记为保持打开状态的33278611
的副本
更新13.09-iOS 11 GM
多亏了kam800的评论(见下文),我做了更多的测试并得出了这些观察结果:
iOS 11中似乎有一个新的守护进程,它要么完全放弃数据推送,要么延迟数据推送的传递:
延期交货
控制台日志
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
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
取消交付问题
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
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 11上从未交付,而在iOS 10上正确交付
更新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
default 08:28:49.354824+0200 apsd apsd:已收到启用主题“onInterface:Non Cellular with payload”的消息,设备令牌的优先级为10:NO courier oversized com.apple.apsd
故障08:33:18.128209 + 0200 DASD基础连接从PID 55:在接收到的消息的解码过程中捕获异常,丢弃传入消息。
异常:解码参数0时异常(调用的#2):
异常:键“NS.objects”的值属于意外的类“NSNull”。允许的课程是'{(
恩萨雷,
NSData,
NSString,
NSN编号,
国家统计局字典,
NSUUID,
_DASActivity,
NSSet,
_达斯菲尔保护,
NSDate,
nw参数,
NWEndpoint
)}'. 通用计算机应用程序
所以这确实是iOS 11中的一个bug,现在在iOS 11Beta 3中已经修复。当在前台或后台接收到静默推送时,现在可以正确调用应用程序:didReceiveMemoteNotify:fetchCompletionHandler
更新
不,它不是固定的,并且仍然在iOS beta 3和4中出现看起来像是iOS 11的一种新行为。iOS 11 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连接到了充电器上——可能是BatteryLevel策略分数高到足以接受一次无声的推送
苹果没有提供有关iOS端行为的官方信息,只有关于服务器端节流的信息:
静默通知并不是让你的应用保持清醒的方式
背景,也不是用于高优先级更新。APNs
将静默通知视为低优先级,可能会导致
{
"aps" : {
"badge" : 0,
"sound" : ""
},
"mydata": {
"foo": "bar"
}
}
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)
}
}
}
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`
}
})
}
}