Detecting organic vs. local notification vs. remote notification app launches

Since iOS 10 and with the UserNotifications framework, detecting wether the user launched the app organically or from a local/remote notification is a bit different than before.

Let’s say I’ve to send an event to my analytics service when user launches the app, I do this using one of these three calls:

  • Analytics.trackAppLaunched(source: .organic)
  • Analytics.trackAppLaunched(source: .localNotification)
  • Analytics.trackAppLaunched(source: .remoteNotification)

I have a NotificationController class that will be the UNUserNotificationCenter delegate. After experimenting a bit with it, I noticed that userNotificationCenter(:didReceive:withCompletionHandler:) is called after application(:didLaunchWithOptions:) but before applicationDidBecomeActive(_:).

In order to not send the event multiple times, we simply need to set a flag when we handle a notification during launch, I called it handledLaunchAnalytics.

func applicationDidBecomeActive(_ application: UIApplication) {
let notificationController = NotificationController.shared
// Track app launch if the notificationController didn't already do it
if !notificationController.handledLaunchAnalytics {
Analytics.trackAppLaunched(source: .Organic)
}
}

view raw
AppDelegate.swift
hosted with ❤ by GitHub

private(set) var handledLaunchAnalytics: Bool = false
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
let atAppLaunch: Bool = (UIApplication.shared.applicationState != .active)
let request: UNNotificationRequest = response.notification.request
if let trigger = request.trigger, trigger is UNPushNotificationTrigger {
// if atAppLaunch == true, call Analytics.trackAppLaunched(source: .remoteNotification)
// and flag handledLaunchAnalytics as true
// then you can handle your remote notification here
} else {
// if atAppLaunch == true, call Analytics.trackAppLaunched(source: .localNotification)
// and flag handledLaunchAnalytics as true
// then you can handle your local notification here
}
completionHandler()
}

view raw
UserController.swift
hosted with ❤ by GitHub

Let’s just not forget to reset handledLaunchAnalytics when the app is going back to background.

If you know of a better way for doing this, I would be happy to hear about you!

 


Leave a Reply

Your email address will not be published. Required fields are marked *