I know similar questions have been asked many times. But it is still very confusing to me after reading those threads, especially after UNUserNotificationCenter
is introduced in iOS 10.
The official documentation mentioned 3 methods where I can handle remote notifications:
userNotificationCenter:willPresentNotification:withCompletionHandler:
to handle a notification when the app is in foreground.userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:
when the app is in background or not running.application:didReceiveRemoteNotification:fetchCompletionHandler:
method of the app delegate. So,
And, more confusing: In case the app is in background, when are the delegate methods called: when the notification message is received? or when the user taps the notification?
Related: iOS push notification: how to detect if the user tapped on notification when the app is in background?
Overview. Use remote notifications (also known as push notifications) to push small amounts of data to devices that use your app, even when your app isn't running. Apps use notifications to provide important information to users. For example, a messaging service sends remote notifications when new messages arrive.
Go to Settings and tap Notifications. Select an app under Notification Style. Under Alerts, choose the alert style that you want. If you turn on Allow Notifications, choose when you want the notifications delivered — immediately or in the scheduled notification summary.
iOS 10 and later:
1) userNotificationCenter willPresent notification: Generally used to decide what to do when user is already inside the app and a notification arrives. You could possibly trigger a remote notification inside the app. After the user taps on the remote notification, method 2 (didReceive response) gets called.
@available(iOS 10.0, *) func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (_ options: UNNotificationPresentationOptions) -> Void) { //Handle push from foreground //When a notification arrives and your user is using the app, you can maybe notify user by showing a remote notification by doing this completionHandler([.alert, .badge, .sound]) //To print notification payload: print(notification.request.content.userInfo) }
2) userNotificationCenter didReceive response: Generally used to redirect the user to a particular screen of the app after user taps on the notification.
@available(iOS 10.0, *) func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { //Handle push from background or closed (or even in foreground) //This method is called when user taps on a notification //To print notification payload: print(response.notification.request.content.userInfo) }
Below iOS 10:
3) application didReceiveRemoteNotification:
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) { //To print notification payload print(userInfo) if #available(iOS 10.0, *) { } else { //Handle remote notifications for devices below iOS 10 if application.applicationState == .active { //app is currently in foreground } else if application.applicationState == .background { //app is in background } else if application.applicationState == .inactive { //app is transitioning from background to foreground (user taps notification) } } }
4) application didFinishLaunchingWithOptions launchOptions: The only scenario which is left for devices below iOS 10 is when app is closed and user taps on the notification launching the app. You'll have to check the following method for this scenario.
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { //To print notification payload: if let notification = launchOptions?[UIApplicationLaunchOptionsKey.remoteNotification] as? [AnyHashable: Any] { print(notification) } }
LaunchOptions is a dictionary indicating the reason the app was launched (if any). The contents of this dictionary may be empty in situations where the user launched the app directly.
Now to answer your questions,
To handle a remote notification when app is in background/inactive, you'll have to add your code in method 2 (userNotificationCenter didReceive response) for devices with iOS 10 and above. Also, you'll have to use method 3 (application didReceiveRemoteNotification) for devices below iOS 10.
To handle remote notifications when app is running in foreground before iOS 10, use the method 3 active state.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With