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

This is a well worn post... but it is still missing an actual solution to the problem (as is pointed out in the various comments).

The original question is about detecting when the app was launched / opened from a push notification, e.g. a user taps on the notification. None of the answers actually cover this case.

The reason can be seen in the call flow when a notification arrives, application:didReceiveRemoteNotification...

gets called when the notification is received AND again when the notification is tapped by the user. Because of this, you can't tell by just looking at UIApplicationState wether the user tapped it.

Additionally, you no longer need to handle the situation of a 'cold start' of the app in application:didFinishLaunchingWithOptions... as application:didReceiveRemoteNotification... is called again after launching in iOS 9+ (maybe 8 as well).

So, how can you tell if the user tap started the chain of events? My solution is to mark the time at which the app begins to come out of the background or cold start and then check that time in application:didReceiveRemoteNotification.... If it is less than 0.1s, then you can be pretty sure the tap triggered the startup.

Swift 2.x

class AppDelegate: UIResponder, UIApplicationDelegate {

  var wakeTime : NSDate = NSDate()        // when did our application wake up most recently?

  func applicationWillEnterForeground(application: UIApplication) {    
    // time stamp the entering of foreground so we can tell how we got here
    wakeTime = NSDate()
  }

  func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
    // ensure the userInfo dictionary has the data you expect
    if let type = userInfo["type"] as? String where type == "status" {
      // IF the wakeTime is less than 1/10 of a second, then we got here by tapping a notification
      if application.applicationState != UIApplicationState.Background && NSDate().timeIntervalSinceDate(wakeTime) < 0.1 {
        // User Tap on notification Started the App
      }
      else {
        // DO stuff here if you ONLY want it to happen when the push arrives
      }
      completionHandler(.NewData)
    }
    else {
      completionHandler(.NoData)
    }
  }
}

Swift 3

class AppDelegate: UIResponder, UIApplicationDelegate {

    var wakeTime : Date = Date()        // when did our application wake up most recently?

    func applicationWillEnterForeground(_ application: UIApplication) {
      // time stamp the entering of foreground so we can tell how we got here
      wakeTime = Date()
    }

  func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {

      // ensure the userInfo dictionary has the data you expect
      if let type = userInfo["type"] as? String, type == "status" {
        // IF the wakeTime is less than 1/10 of a second, then we got here by tapping a notification
        if application.applicationState != UIApplicationState.background && Date().timeIntervalSince(wakeTime) < 0.1 {
          // User Tap on notification Started the App
        }
        else {
          // DO stuff here if you ONLY want it to happen when the push arrives
        }
        completionHandler(.newData)
      }
      else {
        completionHandler(.noData)
      }
    }
}

I have tested this for both cases (app in background, app not running) on iOS 9+ and it works like a charm. 0.1s is pretty conservative too, the actual value is ~0.002s so 0.01 is fine as well.

Examples related to ios

Adding a UISegmentedControl to UITableView Crop image to specified size and picture location Undefined Symbols error when integrating Apptentive iOS SDK via Cocoapods Keep placeholder text in UITextField on input in IOS Accessing AppDelegate from framework? Autoresize View When SubViews are Added Warp \ bend effect on a UIView? Speech input for visually impaired users without the need to tap the screen make UITableViewCell selectable only while editing Xcode 12, building for iOS Simulator, but linking in object file built for iOS, for architecture arm64

Examples related to push-notification

No notification sound when sending notification from firebase in android Registering for Push Notifications in Xcode 8/Swift 3.0? Notification Icon with the new Firebase Cloud Messaging system Android Push Notifications: Icon not displaying in notification, white square shown instead Android: Test Push Notification online (Google Cloud Messaging) Generate .pem file used to set up Apple Push Notifications Will iOS launch my app into the background if it was force-quit by the user? Detect if the app was launched/opened from a push notification Android "hello world" pushnotification example Get push notification while App in foreground iOS

Examples related to ios6

ios simulator: how to close an app Is it possible to install iOS 6 SDK on Xcode 5? How to change navigation bar color in iOS 7 or 6? Detect if the app was launched/opened from a push notification The operation couldn’t be completed. (com.facebook.sdk error 2.) ios6 Evenly space multiple views within a container view how to fix the issue "Command /bin/sh failed with exit code 1" in iphone Setting font on NSAttributedString on UITextView disregards line spacing How do I animate constraint changes? What are Unwind segues for and how do you use them?

Examples related to apple-push-notifications

How to use Apple's new .p8 certificate for APNs in firebase console This certificate has an invalid issuer Apple Push Services registerForRemoteNotificationTypes: is not supported in iOS 8.0 and later Generate .pem file used to set up Apple Push Notifications Will iOS launch my app into the background if it was force-quit by the user? Detect if the app was launched/opened from a push notification Missing Push Notification Entitlement How to fix "no valid 'aps-environment' entitlement string found for application" in Xcode 4.3? Get device token for push notification iOS application: how to clear notifications?

Examples related to uiapplicationdelegate

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