iOS11 swift 静默推送(后台获取、didReceiveRemoteNotification)不再工作

iOS11 swift silent push (background fetch, didReceiveRemoteNotification) is not working anymore

我希望 iOS11 版本能够解决静默推送问题,该问题出现在 iOS 的最新测试版和 GM 版本中。

目前我正在努力理解,为什么我没有收到任何静默推送消息,这实际上应该唤醒我的应用程序以在后台执行一些需要的任务。

在 iOS 10 中,我只是使用后台获取功能并在我的 AppDelegate 中实现了 'wake-up-code',如下面的代码。

在 iOS11 中,注册代码仍然工作正常,我的后端也将推送通知传送到 Apple 的 DEV 服务器(沙盒)和 PROD 服务器(生产版本)。不幸的是,静默推送通知永远不会调用函数 func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void)

我真的错过了 iOS 11 的东西吗?


@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

  // .. some variables here ...

   func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

       // register silent push notification in backend
       application.registerForRemoteNotifications()

       // ... some code here ... 


       // Set Background Fetch Intervall for background services / terminated app
       UIApplication.shared.setMinimumBackgroundFetchInterval(UIApplicationBackgroundFetchIntervalMinimum)

       // ... some code here ... 

       return true
   }

   func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
       let tokenParts = deviceToken.map { data -> String in
           return String(format: "%02.2hhx", data)
       }
       let token = tokenParts.joined()
       logger.log.debug("Device Token: \(token)")

       let realm = RealmController()
       let user = realm.getLoggedInUserObject()

       // Send push token to server
       if let user = user {
           let email = user.email!

           let serverController = ServerController.serverController
           serverController.sendPushToken(token: token, email: email) { status in
               if status == 201 {
                // ... some code here ...
               } else {
               // ... some code here ...
               }
           }
       }
   }
   func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
       logger.log.debug(error)
   }
   func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
       logger.log.debug(userInfo)

       let aps = userInfo["aps"] as! [String: AnyObject]
       if aps["content-available"] as? Int == 1 {
          // .... some silent push tasks here ....
       }
   }
}

最终更新 2017-10-31

Apple 刚刚正式(万圣节)发布了 iOS 11.1

更新 2017-10-09

Apple 今天发布了 iOS11.1 beta 2。他们在发行说明中再次提到以下说明:

Notifications Resolved Issues

Silent push notifications are processed more frequently. (33278611)

我将再次测试此 Beta 2 版本并更新此答案以供参考。

更新 - 测试 -> 在对不同场景进行一些测试后,这个错误似乎在最新的 iOS11.1 beta 2 版本中得到修复。现在只能等官方发布了。在某些论坛中,他们假设 Apple 将在 10 月下旬发布 iOS11.1。


年长post

上周我调查了很多时间以寻找有关此问题的答案。在阅读了 apple release notes(包括已弃用的、更改的和新的功能)后,我测试了以下情况:

我将空函数添加到我的 AppDelegate ,现在静默推送在前台和后台再次工作:

func application(_ application: UIApplication, performFetchWithCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
        logger.log.debug("Perform Fetch with completion handler TEST")
    }

我不确定这个 'workaround' 是否与问题有关,iOS11.

中没有调用以下 function application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void)

不过,如果您发现相同的行为,您可以尝试一下并给我反馈。

更新 2017-09-25

在我的案例中,'silent push' 现在可以在前台和后台模式下工作,但如果应用程序被用户或 OS 暂停,则不会。所以这个问题仍然悬而未决 - 任何帮助表示赞赏! 有关更多信息,另请参阅此线程: Silent pushes not delivered to the app on iOS 11


更新 2017-10-05

Apple 几天前发布了 iOS11.1 测试版。他们在发行说明中提到了以下内容:

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

一些开发人员说这个问题已经通过这个测试版解决了,其他开发人员说这个问题在某些情况下仍然存在。现在,当 Apple 为客户推出 iOS11.1 时会很有趣。

您所遇到的实际上是一个有据可查的行为,而不是错误。

Apple's documentation 说: "The system treats silent notifications as low-priority. You can use them to refresh your app’s content, but the system doesn't guarantee their delivery. In addition, the delivery of silent notifications may be throttled if the total number becomes excessive. The actual number of silent notifications allowed by the system depends on current conditions, but don't try to send more than two or three silent notifications per hour."

总而言之,静默通知不能保证唤醒您的应用。为什么?用户设备后台的应用程序被唤醒的次数越多,电池消耗就越高。

根据 IBM 的声明,它说 "With the advent of iOS 11, Apple has introduced changes in the way they handle certain kinds of push messages. This was done to improve battery life, but comes at a cost of user experience that is likely to affect your app." 您可以找到更多详细信息 here