Apple 远程推送通知在沙盒和生产模式下的行为似乎有所不同

Apple remote push notifications appears to behave different in sandbox- and production-mode

在写我最初的问题时,我在 Ray Wenderlichs tutorial 上找到了关于推送通知的答案。在 Handling Push Notifications 部分,我将代码添加到 AppDelegate.swift,如第一种情况所述。

if let notification = launchOptions?[UIApplicationLaunchOptionsRemoteNotificationKey] as? NSDictionary {
    updateFromSyncData(userInfo: notification)
}

进行此更改后,我可以在应用处于非活动状态时在生产模式下显示推送消息中的文本。

在我添加上面的代码之前,有效负载将在应用程序处于活动状态时进行处理并且在沙盒模式下处于非活动状态,但仅当它处于活动状态时 在生产模式中。

当我注意到这一点时,我更改了代码并在 iphone 连接时进行了测试(在沙盒模式下)。当它工作时,我从 testflight 存档、上传并重新安装了该应用程序。我在这个圈子里转过几次

沙盒和生产之间的这种行为差异是设计使然吗?

我在 xcode 8 beta 5 上使用 swift 3,而 iphone 在 ios 10 beta 6 上使用。

AppDelegate.swift:

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
    if (application.applicationState == .inactive) {
        completionHandler(.newData)
        updateFromSyncData(userInfo: userInfo)
    }
    if (application.applicationState == .active) {
        completionHandler(.newData)
        updateFromSyncData(userInfo: userInfo)
    }
    if (application.applicationState == .background) {
        completionHandler(.newData)
        updateFromSyncData(userInfo: userInfo)
    }
}

func updateFromSyncData(userInfo: NSDictionary) -> Void {
    if let aps = userInfo["aps"] as? NSDictionary {
        let tabbarController = self.window!.rootViewController as! UITabBarController
        let sVC = tabbarController.viewControllers?[1] as! SecondViewController
        // Show payload in SecondViewController etc.
    }
}

您可以查看以下四项内容:

  1. 完成处理程序: completionHandler(.newData) 应该在 处理数据之后而不是之前调用。尝试:

    updateFromSyncData(userInfo: userInfo)
    completionHandler(.newData)
    

    应用程序有 30 秒的时间来处理数据。长时间数据处理的频繁通知也可能导致 iOS 限制远程通知。虽然我不认为这是这里的问题。来自 Apple 的文档:

As soon as you finish processing the notification, you must call the block in the handler parameter or your app will be terminated. Your app has up to 30 seconds of wall-clock time to process the notification and call the specified completion handler block. In practice, you should call the handler block as soon as you are done processing the notification. The system tracks the elapsed time, power usage, and data costs for your app’s background downloads. Apps that use significant amounts of power when processing remote notifications may not always be woken up early to process future notifications.

  1. 主队列: application(_:didReceiveRemoteNotification:fetchCompletionHandler:) 委托方法在后台线程上被调用。检查“// 在 SecondViewController 等中显示负载”中的功能。在主队列上执行 dispatch_async(dispatch_get_main_queue() { ... }.
  2. 功能:如果启用了推送通知以及后台模式下的远程通知,请检查功能。
  3. 强制退出:您是否强制退出应用程序进行测试?在这种情况下,应用程序将不会收到后台通知。正如 Apple 的文档所说:

...if you enabled the remote notifications background mode, the system launches your app (or wakes it from the suspended state) and puts it in the background state when a remote notification arrives. However, the system does not automatically launch your app if the user has force-quit it. In that situation, the user must relaunch your app or restart the device before the system attempts to launch your app automatically again.