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

标签 ios iphone swift apple-push-notifications appdelegate

在写我的原始问题时,我在 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. Completion Handler: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. Main Queue: application(_:didReceiveRemoteNotification:fetchCompletionHandler:) 委托(delegate)方法在后台线程上被调用。检查“//在 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.

关于ios - Apple 远程推送通知在沙盒和生产模式下的行为似乎有所不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38972446/

相关文章:

swift - 使用 Coco/R 翻译源代码后如何测试输入条件?

arrays - 没有更多上下文,表达式类型不明确

ios - rawValue 属性在哪里?

iphone - 从SQLite3(Iphone)获取并显示HTML数据

iphone - 关闭 UIScrollView 下的模态视图更改

swift - 使用多个查询过滤 firebase

ios - 自动续订订阅 iOS swift 决定免费试用

ios - 有没有办法使用 swift 始终在 iOS 中将 Google map 标记固定到其 map 的中心?

ios - Swift Firebase 检查值是否存在

iphone - NSDate 保留发送到释放实例的消息