I have implemented application:didReceiveRemoteNotification:fetchCompletionHandler:
in my application delegate to respond to push notifications.
When a notification is received while the app is in the background, this method is called immediately and I fetch new data and execute the completion block when done. All as per the documentation. However, if I tap the notification alert this method gets called again, resulting in another network call and a UI update. I would have expected this method to be called once for each push notification, not once on receipt and again on action.
How have others implemented this method?
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
[self loadSomeResource:^(NSData *data,NSError *error){
if (error) {
completionHandler(UIBackgroundFetchResultFailed);
}
else if (data){
completionHandler(UIBackgroundFetchResultNewData);
}
else {
completionHandler(UIBackgroundFetchResultNoData);
}
}];
}
Here are the things to be noticed in application:didReceiveRemoteNotification:fetchCompletionHandler: method when you receive a push notification:
1. When the app is not launched (i.e, when the app is neither in background nor in foreground), the method is called once and applicationState will be UIApplicationStateInactive.
2. When the app is in foreground, the method is called once and applicationState will be UIApplicationStateActive.
3. When the app is in background, the method is called twice, once when you receive the push notification, and other time when you tap on that notification. When you receive the push notification, applicationState will be UIApplicationStateBackground and when you tap on that notification, applicationState will be UIApplicationStateInactive.
We can ignore it when the applicationState will be UIApplicationStateBackground and hence we can handle the push notification only once for all the three scenarios.
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
if (application.applicationState == UIApplicationStateBackground) {
completionHandler(UIBackgroundFetchResultNoData);
return;
}
// Do whatever you need here and call completionHandler with appropriate UIBackgroundFetchResult
}
Check your application.applicationState to know if you are in the background or inactive and act accordingly.