Search code examples
iosswiftapple-push-notifications

iOS push notification willPresent notification delegate method is not calling when app is in foreground


I have implemented the push notification in the app. I am getting callbacks on the following delegate method whenever the push comes.

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

I have implemented the following delegate method To show the push notification when the app is in the foreground.

func userNotificationCenter(_ center: UNUserNotificationCenter,
                                    willPresent notification: UNNotification,
                                    withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void)
    { 
       completionHandler([.alert, .badge, .sound])
    }

Unfortunately, it is not working every time. Irrespective of the app state I'm getting the callback on didReceiveRemoteNotification method. Is there any particular reason for this behavior? Am I missing something?

Thanks in advance


Solution

  • I think you have to use the userNotificationCenter with the "didReceive response" signature instead of the application(didReceiveRemoteNotification userInfo:..)

    // MARK: Notification handling
    
    // If the app is in the background
    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
        let id = response.notification.request.identifier
        print("Received notification with ID = \(id)")
    
        completionHandler()
    }
    
    // If the app is in the foreground
    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        let id = notification.request.identifier
        print("Received notification with ID = \(id)")
    
        completionHandler([.sound, .alert])
    }
    

    Also have your AppDelegate be UNUserNotificationCenter delegate.

    class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
    
        var window: UIWindow?
    
        func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
            UNUserNotificationCenter.current().delegate = self
        }
    .
    .
    .
        }