UNUserNotificationCenter didRecieve Response is not called if App is terminated

15,838

Solution 1

From my own experimentation, receiving local notifications in Swift 3 & Xcode 8 are as follows:

Conformance

  • Conform to UNUserNotificationCenterDelegate

    class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate { .... }
    
  • Register as Notification Center's delegate:

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    
        let center = UNUserNotificationCenter.current()
        center.delegate = self
    
        return true
    }
    

Delegate Methods

  • Respond to missed notifications (e.g. user viewing app when notification sent)

    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: (UNNotificationPresentationOptions) -> Void) {
        print(notification.request.content.userInfo)
    }
    
  • Respond to actioned notifications (e.g. user opened notification)

    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: () -> Void) {
        print(response.notification.request.content.userInfo)
    }
    

Solution 2

Swift 3.1 Update

  • Conform to UNUserNotificationCenterDelegate

  • Register as Notification Center's delegate:

UNUserNotificationCenter.current().delegate = self
  • Delegate Methods
public func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
    print(response.notification.request.content.categoryIdentifier)
}

public func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
    print(notification.request.content.categoryIdentifier)
}
Share:
15,838
Kautsya Kanu
Author by

Kautsya Kanu

Updated on June 08, 2022

Comments

  • Kautsya Kanu
    Kautsya Kanu almost 2 years

    UNUserNotificationCenter function is not called on clicking Action Button Chat in Notification after 3D Touch if App is not active(not even in Background or say has terminated). I used "attach to process by name" in Xcode to debug app when app was terminated. Here is the Code:

    import UIKit
    import Mixpanel
    import UserNotifications
    
    @UIApplicationMain
    
    class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
    
        func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
            //setup mixpanel
    
            self.handlePushNotificationWithUserInfo(launchOptions: launchOptions)
    
            //ask for push notification perms
            return true
        }
    

    When Notification Pop-up (Sent from MixPanel) this function is called first,

    Call 1:

        func handlePushNotificationWithUserInfo(launchOptions: [NSObject: AnyObject]?) {
            //Handle PushNotification when app is opened
        }
    

    Then It goes here,

    Call 2:

        //register for notification
        func application(_ application: UIApplication, didRegister notificationSettings: UIUserNotificationSettings) {
    
            if #available(iOS 10.0, *) {
                let center = UNUserNotificationCenter.current()
                center.requestAuthorization(options: [.alert, .sound]) { (granted, error) in
                    // Enable or disable features based on authorization.
                }
                center.delegate = self
    
                let actionChat = UNNotificationAction(identifier: Constants.ActionType.CHAT.rawValue, title: "Chat", options: [.foreground])
                let categoryOptions = UNNotificationCategoryOptions(rawValue: 0)
                let customerSupportCategory = UNNotificationCategory(identifier: Constants.NotificationType.CUSTOMER_SUPPORT.rawValue, actions: [actionChat], intentIdentifiers: [], options: categoryOptions)
                center.setNotificationCategories([customerSupportCategory])
            }
    
            application.registerForRemoteNotifications()
        }
    

    Call 3:

        // remote notification
        func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
            ....Some Code....
        }
    

    But below function is not called. But if app is running in background then below function is called and all works fine OTHERWISE App comes to foreground and chat does not after that.

        // action buttons in enhanced Notification
        @available(iOS 10, *)
        func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: () -> Void) {
            guard let action = Constants.ActionType(rawValue: response.actionIdentifier) else {
                completionHandler()
                return
            }
            switch action {
            case .CHAT:
                _ = self.handleRemoteUrl(NSURL(string: "chat") as? URL)
            default:
                _ = self.handleRemoteUrl(NSURL(string: "chat") as? URL)
            }
            completionHandler()
        }
    
        @available(iOS 10.0, *)
        func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: (UNNotificationPresentationOptions) -> Void) {
            completionHandler([.alert, .sound])
        }
    }
    

    This function is never called may be because it's depreciated in iOS 10 over userNotificationCenter(), not sure. Please explain this also..

        func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
            ....Some Code....
        }
    

    I am using iPhone 6s iOS 10 as debugging device. XCode 8 beta-3

  • Kautsya Kanu
    Kautsya Kanu over 7 years
    Yes, Actually I have done all these steps.. Later I found my mistake but have not added answer and expiation yet, So I just added RegisterNotification.sharedHandler.registerFor3dTouchInNotif‌​ication(appDelegate: self) in func handlePushNotificationWithUserInfo(launchOptions: [NSObject: AnyObject]?) which register category every time we get notification, Not sure if it is correct way but It solved my problem..
  • Hugues BR
    Hugues BR over 6 years
    not the case anymore with UNUserNotificationCenter, delegate is always called...
  • ArgaPK
    ArgaPK about 6 years
    could you please tel me which method gets executed when your app is in background and receives notification?
  • ArgaPK
    ArgaPK about 6 years
    @HuguesBR could you please tel me which method gets executed when the app is in background and receives notiification?
  • Finn Gaida
    Finn Gaida over 5 years
    This fixed it for me! Emphasis lies on registering the Notification center delegate directly in appDidFinishLaunching and no later.
  • djneely
    djneely over 5 years
    Thank you! My issue was the appDidFinishLaunching as I have notification registration being handled after login. For the delegate I moved this to the appDidFinishLaunching and things are working well.