2

When the app is closed and the user taps on a notification:

1) didFinishLaunchingWithOptions is called with a remoteNotification object. I set the rootViewController here as expected

2) userNotificationCenter(_, didReceive, withCompletionHandler) is also called.

The thing is, I don't want to do anything on step 2 because I already handled the notification on step 1). But, if the app was in the foreground or background, I do want to handle the notification in step 2). I don't know how to differentiate these two cases.

  • What about trying to set the rootViewController in the userNotificationCenter function instead of didFinishLaunchingWithOptions? This way it is called only once, because, the userNotificationCenter is a Delegate function which is called when a user taps on a notification. – Charlie Pico Jun 22 '17 at 18:40
  • Because I do need to set a rootViewController in didFinishLaunchingWithOptions, otherwise the app crashes – Martin Dutra Jun 22 '17 at 19:00
  • Mhmmm, you could add a variable which sets if the user went to the background state or if the app is being just opened. So when the user goes to background, lets set wasInBackground = true, so if wasInBackground is true you handle the notification, if not, then don't. – Charlie Pico Jun 22 '17 at 19:14
  • Just to be sure, did you **verify** that they are both being called upon taping on notification or it's just that you thought that's what's going to happen? – mfaani Jun 26 '17 at 18:45

2 Answers2

0

I think they are for separate concerns.

That is userNotificationCenter(_, didReceive, withCompletionHandler) is for handling Responses. What action did the user click, did they just swipe to clear it? Did they respond to the message right there?

But the didFinishLaunchingWithOptions is there only for receiving a callback, it's just there to tell you that the app was launched through the notification after it was killed/suspended...be aware...and here's your chance to do launch/do whatever you usually do during app launches

mfaani
  • 33,269
  • 19
  • 164
  • 293
0

You can use a flag variable in AppDelegate class. The initial value is false, with the name isAppActive. This variable will set to true whenever func applicationDidBecomeActive(_ application: UIApplication) is called.

So, you can check if app already finished the first setup/initialization or not. AppDelegate instance is a shared instance so you can check it anywhere at runtime.

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool is called only once when app is completely loaded into RAM. After that, you can check isAppActive value. Ex:

func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void)
    if isAppActive {
        // Do your logic here
    }
Neklas
  • 504
  • 1
  • 9