push notification handling

27,334

Solution 1

The wording here is confusing, especially around the word backgrounding.

When the application is truly not loaded in memory (e,g. when you launch it the splash screen shows up etc), then application:didFinishLaunchingWithOptions is called, and you can get the push notification as follows:

NSDictionary *remoteNotif = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];

if(remoteNotif)
{
    //Handle remote notification
}

If the app is loaded in memory and is ACTIVE (e.g. the app is currently open on the device) then only application:didReceiveRemoteNotification: is called.

If the app is loaded in memory but is not ACTIVE and NOT BACKGROUNDING (e.g., you launched the app, then pressed the home button, and waited 10 seconds), and then you click the action button on a push notification, only didReceiveRemoteNotification is called.

You can capture this case as follows:

-(void)application:(UIApplication *)app didReceiveRemoteNotification:(NSDictionary *)userInfo
{
    if([app applicationState] == UIApplicationStateInactive)
    {
        //If the application state was inactive, this means the user pressed an action button
        // from a notification. 

    //Handle notification
    }
}

Solution 2

As per iOS 9.1 scenario I have tested push notification in Kill mode where my application is not running in any mode at that time if I tap on push notification than the system will call first,

- (void)application:(UIApplication*)application didReceiveRemoteNotification:(NSDictionary *)userInfo{

//your code execution will here.

}

And second method call will be,

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

//Your initial code execution.

}

This scenario I have tested in my application.

Share:
27,334
Joey
Author by

Joey

Building mobile (currently iPad) apps to make learning more bearable--I mean, fun! Send me a message if this interests you. Email's just joey at gyrovation.

Updated on December 17, 2020

Comments

  • Joey
    Joey over 3 years

    I'm reading Apple's docs on

    Handling Local and Remote Notifications

    and it looks to me to have conflicting statements. Can someone clear up these confusion points? Let's speak strictly of remote notification (versus local) for now.

    The docs say that if the action button on the notification is pressed, it calls application:didFinishLaunchingWithOptions and passes in the notification payload. Later it says if the app is running in the foreground, it delivers the notification via application:didReceiveRemoteNotification:. This implies to me that when the app is backgrounded or not running, then application:didFinishLaunchingWithOptions is called. Otherwise, application:didReceiveRemoteNotification: is called.

    Later, there is an iOS Note saying the following:

    "iOS Note: In iOS, you can determine whether an application is launched as a result of the user tapping the action button or whether the notification was delivered to the already-running application by examining the application state. In the delegate’s implementation of the application:didReceiveRemoteNotification: or application:didReceiveLocalNotification: method, get the value of the applicationState property and evaluate it. If the value is UIApplicationStateInactive, the user tapped the action button; if the value is UIApplicationStateActive, the application was frontmost when it received the notification."

    This implies to me that application:didReceiveRemoteNotification: is called both when the app is already foregrounded and if the user presses the action button (or slides the action slider in iOS 5) to foreground/launch the app.

    The source of my confusion might be with the first portion where the docs imply the notification payload is sent with the application:didFinishLaunchingWithOptions: method or with a misunderstanding of what a "running" application is (is a backgrounded app considered "running"?). The documentation for application:didReceiveRemoteNotification: states it is called for "running" applications.

    So, to summarize, could I get clarification on:

    1) Is application:didReceiveRemoteNotification: always called when the app is foregrounded or when the user selects to "act" on the notification? If not, how do we make sense of the iOS Note on determining the Application State being active or inactive?

    2) Is a backgrounded app "running", at least in the sense of the docs claiming application:didReceiveRemoteNotification is called for running apps?

    3) For completion, is a backgrounded app UIApplicationStateInactive or Active?

  • mcont
    mcont about 10 years
    Is didReceiveRemoteNotification called in the first case you explained? Is it enough to implement my code in both methods you've written? Won't the code run twice? Thanks.
  • dvkch
    dvkch almost 10 years
    this in incorrect: if you have the notification center visible or control center for instance, the app is considered inactive. do you have any suggestion on how to determine the "becoming active from background" kind ?
  • valvoline
    valvoline over 9 years
    also note that the same behavious is related to didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler NS_AVAILABLE_IOS(7_0);
  • sam_smith
    sam_smith over 9 years
    Good answer here which seems to be dealing with some of the other issues: stackoverflow.com/questions/5835806/… basically checking if the app is inactive of in the background: if (state == UIApplicationStateBackground || state == UIApplicationStateInactive). A bit of work with this could probably satisfy all the different cases
  • Nico
    Nico over 7 years
    How did you test this scenario, Please explain ?
  • Gautam Sareriya
    Gautam Sareriya over 7 years
    Nico, I have print the Log in document directory file to check, which one method will be called in kill mode of push notification.
  • nr5
    nr5 about 7 years
    What if I tap the home button, and the send notification. I see the notification, but I choose to tap the app icon, instead of the notification. My app will have no idea of the notification?