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

Posted

技术标签:

【中文标题】Apple 远程推送通知在沙盒模式和生产模式下的行为似乎不同【英文标题】:Apple remote push notifications appears to behave different in sandbox- and production-mode 【发布时间】:2016-08-16 10:25:48 【问题描述】:

在写我最初的问题时,我在 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 的文档:

完成通知处理后,您必须致电 在 handler 参数中阻止,否则您的应用程序将被终止。您的 应用程序有长达 30 秒的挂钟时间来处理 通知并调用指定的完成处理程序块。在 练习,你应该在完成后立即调用处理程序块 处理通知。系统跟踪经过时间、电量 应用程序后台下载的使用量和数据成本。应用程序 处理远程通知时使用大量电力 可能并不总是被提早唤醒以处理未来的通知。

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

...如果您启用了远程通知后台模式, 系统启动您的应用程序(或将其从挂起状态唤醒) 并在收到远程通知时将其置于后台状态 到达。但是,如果出现以下情况,系统不会自动启动您的应用程序 用户已强制退出它。在这种情况下,用户必须重新启动 您的应用程序或在系统尝试启动之前重新启动设备 您的应用会再次自动自动运行。

【讨论】:

谢谢。我按照您的建议 #1 更改了顺序并在函数之后调用了完成处理程序。这解决了我的问题。

以上是关于Apple 远程推送通知在沙盒模式和生产模式下的行为似乎不同的主要内容,如果未能解决你的问题,请参考以下文章

Apple 在沙盒上推送通知

MobileFirst Starter - 生产模式下的 Bluemix 推送通知失败

在使用 PayPal API 时经常在沙盒模式和生产模式之间切换是一种不好的做法吗?

Azure iOS 推送通知在生产模式下未收到?

推送通知在开发和生产模式下如何工作(pushwoosh)

将推送证书从 2 个(沙盒和生产)更改为 1 个证书(沙盒/生产)