How do I tell if my iPhone app is running when a Push Notification is received?

20,099

Solution 1

The UIApplication delegate has the method

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

which you need to implement. This receives the notification when the app is running.

If your app is not currently running and a notification is received then your app can be launched with

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

with the notification details held in the launchOptions dictionary. if the dictionary is nil then the user tapped the application icon as normal.

Solution 2

Here's the more appropriate way of handling active/inactive state of the app.

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {   
        // check for the app state
        UIApplicationState state = [application applicationState];

        if (state == UIApplicationStateActive) {
            //the app is in the foreground, so here you do your stuff since the OS does not do it for you
            //navigate the "aps" dictionary looking for "loc-args" and "loc-key", for example, or your personal payload)
        }

    application.applicationIconBadgeNumber = 0;
}

didReceiveRemoteNotification: is called when the app is running, yes, but when it is suspended, the iOS takes care of putting up the badge, etc. If the app is in the foreground, the OS does nothing, and just calls your didReceiveRemoteNotification:.

Solution 3

Depending upon what you mean by "launched", you are either looking for:

  • Kevin's answer above (differentiates between launched or not launched)
  • or this (differentiates between suspended or active, but already launched):

Use a flag that is set true when the application becomes active, and false when the application is not active.

Flag (in header file [.h]):

BOOL applicationIsActive;

Code (in implementation file [.m]):

- (void)applicationDidBecomeActive:(UIApplication *)application {
    applicationIsActive = YES;
}

- (void)applicationWillResignActive:(UIApplication *)application {
    applicationIsActive = NO;
}

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
    if (applicationIsActive) {
        // Handle notification in app active state here
    }
    else {
        // Handle notification in app suspended state here
    }

This works because when the application is suspended, the OS calls "applicationDidReceiveRemoteNotification" before it calls "applicationDidBecomeActive" during the "wake-up" process.

The "complete" answer is actually Kevin's answer plus this answer.

Hope this helps.

Solution 4

If you are going to check applicationState on iOS less than 4, you'll need to check that applicationState is supported:

if ([application respondsToSelector:@selector(applicationState)] ){
  // Safe to check applicationState
  UIApplicationState state = [application applicationState];
}

Solution 5

The Apple documentation for push notifications explains this:

However, there are two situations where applicationDidFinishLaunching: is not a suitable implementation site:

  • The application is running when the notification arrives.
  • The notification payload contains custom data that the application can use.

In the first case, where the application is running when iPhone OS receives a remote notification, you should implement the application:didReceiveRemoteNotification: method of UIApplicationDelegate if you want to download the data immediately. After downloading, be sure to remove the badge from the application icon. (If your application frequently checks with its provider for new data, implementing this method might not be necessary.)

This means that if your application:didReceiveRemoteNotification: delegate method is called, your app is running.

Share:
20,099
thebossman
Author by

thebossman

Updated on February 08, 2020

Comments

  • thebossman
    thebossman over 4 years

    I am sending Push Notifications to my iPhone app, and I'd like a different set of instructions to execute depending on whether the app is already launched or not. I'm new to iPhone development, and while I suspect UIApplication or my project's AppDelegate class has the solution, I haven't found a good answer. Is there an easy way to check for this?