didReceiveRemoteNotification: fetchCompletionHandler: open from icon vs push notification

Mike V picture Mike V · Feb 28, 2014 · Viewed 37.7k times · Source

I'm trying to implement background push notification handling, but I'm having issues with determining whether the user opened the app from the push notification that was sent as opposed to opening it from the icon.

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {

    //************************************************************
    // I only want this called if the user opened from swiping the push notification. 
    // Otherwise I just want to update the local model
    //************************************************************
    if(applicationState != UIApplicationStateActive) {
        MPOOpenViewController *openVc = [[MPOOpenViewController alloc] init];
        [self.navigationController pushViewController:openVc animated:NO];
    } else {
        ///Update local model
    }

    completionHandler(UIBackgroundFetchResultNewData);
}

With this code, the app is opening to the MPOOpenViewController regardless of how the user opens the app. How can I make it so that the view controller is only pushed if they open the app from swiping the notification?

With the same code, this worked on iOS 6, but with the new iOS 7 method, it doesn't behave how I want it to.

Edit: I'm trying to run the app on iOS 7 now, and we are not supporting any version prior to iOS 7. I used this same exact code in the iOS 6 version of the method (without the completion handler) and it behaved the way I'd expect it to. You'd swipe the notification and this would get called. If you opened from the icon, the method would never be called.

Answer

Mike V picture Mike V · Feb 28, 2014

Ok I figured it out. The method is actually called twice (once when it receives the push, and once when the user interacts with the icon or the notification).

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {

    if(application.applicationState == UIApplicationStateInactive) {

        NSLog(@"Inactive");

        //Show the view with the content of the push

        completionHandler(UIBackgroundFetchResultNewData);

    } else if (application.applicationState == UIApplicationStateBackground) {

        NSLog(@"Background");

        //Refresh the local model

        completionHandler(UIBackgroundFetchResultNewData);

    } else {

        NSLog(@"Active");

        //Show an in-app banner

        completionHandler(UIBackgroundFetchResultNewData);

    }
}

Thanks Tim Castelijns for the following addition:

Note: the reason it's called twice is due to the Payload having content_available : 1. If you remove the key and its value, then it will only run upon tapping. This will not solve everyone's problem since some people need that key to be true