Complete Implementation for Detecting App Launch from Push Notifications in iOS

Dec 06, 2025 · Programming · 12 views · 7.8

Keywords: iOS Push Notifications | App Lifecycle | UIApplicationDelegate

Abstract: This article provides a comprehensive guide on detecting whether an iOS app was launched or opened from a push notification. It covers the complete detection scheme from cold launch to background wake-up by analyzing the app lifecycle and UIApplicationDelegate methods. Based on high-scoring Stack Overflow answers with supplementary information, it offers practical code examples and best practice recommendations.

In iOS app development, accurately detecting whether an app was launched from a push notification is a common but error-prone requirement. This article explains in detail how to implement this functionality in different app states based on the UIApplicationDelegate protocol.

App Lifecycle and Push Notifications

Understanding the iOS app lifecycle is essential for correctly handling push notification launch detection. An app can be in several states: completely closed (cold launch), suspended in the background, or running in the foreground. The arrival of push notifications and user interactions trigger different delegate methods.

Detection During Cold Launch

When the app is completely closed (either terminated by the system or manually by the user), tapping a push notification triggers a cold launch. In this case, the application:didFinishLaunchingWithOptions: method is called, and the launchOptions parameter contains the push notification information.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    if (launchOptions != nil) {
        NSDictionary *notification = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
        if (notification) {
            NSLog(@"App launched from remote push notification");
            // Handle push notification logic
            [self handleNotification:notification];
        }
    }
    return YES;
}

For local push notifications, use the UIApplicationLaunchOptionsLocalNotificationKey key to retrieve the notification information. This approach applies when the app is relaunched via push notification after being terminated by the system or manually killed by the user.

Detection During Background Wake-up

When the app is running in the background, tapping a push notification wakes up the app and brings it to the foreground. In this scenario, application:didFinishLaunchingWithOptions: is not called; instead, the application:didReceiveRemoteNotification: method is triggered.

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
    if (application.applicationState == UIApplicationStateInactive || application.applicationState == UIApplicationStateBackground) {
        NSLog(@"App opened from push notification while in background");
        // Handle push notification logic
        [self handleNotification:userInfo];
    }
}

By checking the application.applicationState property, you can distinguish whether the app received the notification while in the foreground (UIApplicationStateActive) or was opened from the background via notification (UIApplicationStateInactive or UIApplicationStateBackground). For local push notifications, the corresponding delegate method is application:didReceiveLocalNotification:.

Complete Lifecycle Handling Solution

In practical development, more complex scenarios need to be handled. According to testing, the sequence of app lifecycle method calls in iOS 10 and above is as follows:

A robust implementation requires maintaining state variables in the AppDelegate to track push notification information:

@interface AppDelegate ()
@property (nonatomic, strong) NSDictionary *notificationUserInfo;
@end

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    self.notificationUserInfo = nil;
    
    if (launchOptions != nil) {
        NSDictionary *notification = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
        if (notification) {
            self.notificationUserInfo = notification;
        }
    }
    return YES;
}

- (void)applicationWillEnterForeground:(UIApplication *)application {
    self.notificationUserInfo = nil;
}

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
    if (application.applicationState == UIApplicationStateInactive) {
        self.notificationUserInfo = userInfo;
    }
}

- (void)applicationDidBecomeActive:(UIApplication *)application {
    if (self.notificationUserInfo) {
        [self openViewFromNotification:self.notificationUserInfo];
        self.notificationUserInfo = nil;
    }
}

- (void)openViewFromNotification:(NSDictionary *)userInfo {
    // Open the appropriate view based on push notification content
    NSLog(@"Opening view from push notification: %@", userInfo);
}

@end

Handling Special Cases

One special case to note: when the app is running in the foreground and the user is viewing it via the app switcher, if a push notification is received at this moment, only the didReceiveRemoteNotification: method is called, while applicationWillEnterForeground and didFinishLaunchingWithOptions are not invoked. In this scenario, additional state management is required to ensure proper handling.

Best Practice Recommendations

  1. Always handle the final response logic for push notifications in applicationDidBecomeActive, as this is when the app truly becomes active.
  2. Use state variables to track push notification information to avoid logical errors in the complex sequence of lifecycle method calls.
  3. For push notifications requiring background refresh, implement the application:didReceiveRemoteNotification:fetchCompletionHandler: method.
  4. Test all possible scenarios: push notification handling in cold launch, warm launch, background suspension, foreground running, etc.

Through the methods described above, developers can accurately detect whether an iOS app was launched from a push notification and execute corresponding business logic based on different app states and push types.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.