Detect if the app was launched/opened from a push notification Detect if the app was launched/opened from a push notification ios ios

Detect if the app was launched/opened from a push notification


See This code :

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo{    if ( application.applicationState == UIApplicationStateInactive || application.applicationState == UIApplicationStateBackground  )    {         //opened from a push notification when the app was on background    }}

same as

-(void)application:(UIApplication *)application didReceiveLocalNotification (UILocalNotification *)notification


late but maybe useful

When app is not running

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

is called ..

where u need to check for push notification

NSDictionary *notification = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];if (notification) {    NSLog(@"app recieved notification from remote%@",notification);    [self application:application didReceiveRemoteNotification:notification];} else {    NSLog(@"app did not recieve notification");}


The issue we had was in correctly updating the view after the app is launched. There are complicated sequences of lifecycle methods here that get confusing.

Lifecycle Methods

Our testing for iOS 10 revealed the following sequences of lifecycle methods for the various cases:

DELEGATE METHODS CALLED WHEN OPENING APP    Opening app when system killed or user killed        didFinishLaunchingWithOptions        applicationDidBecomeActive    Opening app when backgrounded        applicationWillEnterForeground        applicationDidBecomeActiveDELEGATE METHODS CALLED WHEN OPENING PUSH    Opening push when system killed        [receiving push causes didFinishLaunchingWithOptions (with options) and didReceiveRemoteNotification:background]        applicationWillEnterForeground        didReceiveRemoteNotification:inactive        applicationDidBecomeActive    Opening push when user killed        didFinishLaunchingWithOptions (with options)        didReceiveRemoteNotification:inactive [only completionHandler version]        applicationDidBecomeActive    Opening push when backgrounded        [receiving push causes didReceiveRemoteNotification:background]        applicationWillEnterForeground        didReceiveRemoteNotification:inactive        applicationDidBecomeActive

The problem

Ok, so now we need to:

  1. Determine if the user is opening the app from a push
  2. Update the view based on the push state
  3. Clear the state so that subsequent opens don't return the user to the same position.

The tricky bit is that updating the view has to happen when the application actually becomes active, which is the same lifecycle method in all cases.

Sketch of our solution

Here are the main components of our solution:

  1. Store a notificationUserInfo instance variable on the AppDelegate.
  2. Set notificationUserInfo = nil in both applicationWillEnterForeground and didFinishLaunchingWithOptions.
  3. Set notificationUserInfo = userInfo in didReceiveRemoteNotification:inactive
  4. From applicationDidBecomeActive always call a custom method openViewFromNotification and pass self.notificationUserInfo. If self.notificationUserInfo is nil then return early, otherwise open the view based on the notification state found in self.notificationUserInfo.

Explanation

When opening from a push didFinishLaunchingWithOptions or applicationWillEnterForeground is always called immediately before didReceiveRemoteNotification:inactive, so we first reset notificationUserInfo in these methods so there's no stale state. Then, if didReceiveRemoteNotification:inactive is called we know we're opening from a push so we set self.notificationUserInfo which is then picked up by applicationDidBecomeActive to forward the user to the right view.

There is one final case which is if the user has the app open within the app switcher (i.e. by double tapping the home button while the app is in the foreground) and then receives a push notification. In this case only didReceiveRemoteNotification:inactive is called, and neither WillEnterForeground nor didFinishLaunching gets called so you need some special state to handle that case.

Hope this helps.