为什么didReceiveRemoteNotification没有被调用但是didReceiveRemoteNotification:当我的应用程序在前台时调用fetchCompletionHandler?

时间:2015-04-28 20:37:32

标签: ios swift apple-push-notifications appdelegate

如果我覆盖

override func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
    println("hey)
}

当我发送推送通知时,我成功地使用应用程序在前台调用了该方法。

如果我覆盖

override func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
    println("hey")
}

在前台发送应用程序通知时,我没有调用该方法。为什么第一个工作,但第二个不适用于应用程序在前台?

请注意,我一次只实现其中一个。不是两个在同一时间。

2 个答案:

答案 0 :(得分:15)

您应该使用回调版本,除非您需要支持ios< 7(当它被引入时)。当您使用Swift时,我预计情况并非如此。

旧方法可以追溯到ios3,除了名称之外全部弃用:

  

尽可能实现application:didReceiveRemoteNotification:fetchCompletionHandler:方法而不是此方法。如果您的委托实现了这两种方法,则app对象会调用application:didReceiveRemoteNotification:fetchCompletionHandler:方法。

旧版本也会提供不同的结果,具体取决于应用程序是实时(前景或后台)还是从冷启动启动。在后一种情况下,它不会被调用,你需要截取launchOptions上的didFinishLaunchingWithOptions字典来获取infoDict:

  

如果远程通知到达时应用程序未运行,该方法将启动应用程序并在启动选项字典中提供相应的信息。该应用程序不会调用此方法来处理该远程通知。

使用回调版本。它适用于所有情况。 你不必使用完成处理程序/块,在这种情况下效果是相同的(好的,与更新的方法更一致)。

更新

抱歉,Apple说必须“尽快”调用完成块 - 在操作系统放弃你之前你有30秒的时间。这可能是您警告的来源。

  

一旦完成处理通知,您必须在处理程序参数中调用该块,否则您的应用程序将被终止。您的应用程序有最多30秒的挂钟时间来处理通知并调用指定的完成处理程序块。实际上,您应该在处理完通知后立即调用处理程序块。

所以请调用完成块:

        completionHandler(UIBackgroundFetchResult.NoData)

我一直在使用这个方法没有调用完成块并且没有遇到任何问题,但我现在要添加一个只是为了安全。 Apple建议,如果你不这样做,你的应用程序将不会被预见到,但我在实践中没有看到它。

答案 1 :(得分:0)

您是否使用UIUserNotificationType注册了至少一个UIApplication:registerUserNotificationSettings:

如果您没有注册徽章,声音或警报,那么您只能接收静默通知,这些通知仅通过FetchCompletionHandler提供。