Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is didReceiveRemoteNotification not called but didReceiveRemoteNotification:fetchCompletionHandler called when my app is in the foreground?

If I override

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

I successfully have the method called with the app in the foreground when I send a push notification.

If I override

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

I don't get any call to the method when sending a notification with the app in the foreground. Why does the first one work, but the second one doesn't when the app is in the foreground?

Note that I am only implementing one of these at a time. Not both at the same time.

like image 674
Adam Johns Avatar asked Apr 28 '15 20:04

Adam Johns


1 Answers

You should use the callback version unless you need to support ios<7 (when it was introduced). As you are using Swift I expect that is not the case.

The older method goes back to ios3 and is deprecated in all but name:

Implement the application:didReceiveRemoteNotification:fetchCompletionHandler: method instead of this one whenever possible. If your delegate implements both methods, the app object calls the application:didReceiveRemoteNotification:fetchCompletionHandler: method.

The older version will also give different results depending on whether the app is live (foreground or background) or launches from a cold start. In the latter case, it will not get called, and you will need to intercept the launchOptions dict on didFinishLaunchingWithOptions to get at the infoDict:

If the app is not running when a remote notification arrives, the method launches the app and provides the appropriate information in the launch options dictionary. The app does not call this method to handle that remote notification.

Use the callback version. It works for all cases. You don't have to use the completion handler/block, in which case the effect is the same (well, more consistent with the newer method).

update

sorry, Apple says you do have to call the completion block "as soon as possible" - you have 30 seconds to do so before the OS gives up on you. This might be the source of your warning.

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.

So call the completion block:

        completionHandler(UIBackgroundFetchResult.NoData)

I have been using this method without calling that completion block and haven't experienced any problems, but i will add one now just to be safe. Apple suggests that if you don't, your app won't get foregrounded but I have not seen that in practice.

like image 73
foundry Avatar answered Oct 18 '22 21:10

foundry