ios – Push notification not working in SwiftUI app when used a separate class for managing MessagingDelegate, UNUserNotificationCenterDelegate


In my SwiftUI app(Xcode 15.0.1, Test iPhone OS: 16.7), Push notification from Firebase is not working when used a separate class for managing MessagingDelegate, UNUserNotificationCenterDelegate but it works when I put everything inside the AppDelegate class.

My AppDelegate looks like this:

    class AppDelegate: NSObject, UIApplicationDelegate {
    
        let remoteNotificationManager = RemoteNotificationManager()
        func application(
            _ application: UIApplication,
            didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
        ) -> Bool {
            application.registerForRemoteNotifications()
            configureFirebase()
            remoteNotificationManager.configure()
            return true
        }
    }

My RemoteNotificationManager class looks like this:

final class RemoteNotificationManager: NSObject {

    func configure() {
        Messaging.messaging().delegate = self
        UNUserNotificationCenter.current().delegate = self
    }
}

// MARK: - Firebase MessagingDelegate

extension RemoteNotificationManager: MessagingDelegate {

    // This fcmToken will be used for device specific notification from Firebase
    func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {
        // TODO: Remove print in integration
        if let fcmToken = fcmToken {
            print("RemoteNotificationManager fcm from api: \(fcmToken)")
        }
    }
}

// MARK: - UNUserNotificationCenterDelegate

extension RemoteNotificationManager: UNUserNotificationCenterDelegate {

    func application(
        _ application: UIApplication,
        didFailToRegisterForRemoteNotificationsWithError error: Error
    ) {
        NSLog("Failed to register remote notification. %@", error.localizedDescription)
    }

    func application(
        _ application: UIApplication,
        didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data
    ) {
        Messaging.messaging().apnsToken = deviceToken
    }

    // This method is called when user taps on a notification
    func userNotificationCenter(
        _ center: UNUserNotificationCenter,
        didReceive response: UNNotificationResponse,
        withCompletionHandler completionHandler: @escaping () -> Void
    ) {
        let userInfo = response.notification.request.content.userInfo
        // TODO: Remove print, integrate
        print("RemoteNotificationManager didReceive: \(userInfo)")
        completionHandler()
    }

    // This method is called when user already in the app and notification arrived
    func userNotificationCenter(
        _ center: UNUserNotificationCenter,
        willPresent notification: UNNotification,
        withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void
    ) {
        // TODO: Remove print, integrate completionHandler
        print("RemoteNotificationManager willPresent: \(notification.request.content.userInfo)")
        completionHandler(.banner)
    }
}

In this code above doesn’t receive deviceToken and Messaging.messaging().apnsToken remains nil always. But if I removed the class RemoteNotificationManager, and put all the codes inside AppDelegate like below it works:

class AppDelegate: NSObject, UIApplicationDelegate {

    func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
    ) -> Bool {
        application.registerForRemoteNotifications()
        configureFirebase()
        configureRemoteNotification()
        return true
    }
}

extension AppDelegate {

    private func configureFirebase() {
        FirebaseApp.configure()
    }

    private func configureRemoteNotification() {
        Messaging.messaging().delegate = self
        UNUserNotificationCenter.current().delegate = self
    }
}

// MARK: - UNUserNotificationCenterDelegate

extension AppDelegate: UNUserNotificationCenterDelegate {

    func application(
        _ application: UIApplication,
        didFailToRegisterForRemoteNotificationsWithError error: Error
    ) {
        NSLog("Failed to register remote notification. %@", error.localizedDescription)
    }

    func application(
        _ application: UIApplication,
        didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data
    ) {
        Messaging.messaging().apnsToken = deviceToken
    }

    // This method is called when user taps on a notification
    func userNotificationCenter(
        _ center: UNUserNotificationCenter,
        didReceive response: UNNotificationResponse,
        withCompletionHandler completionHandler: @escaping () -> Void
    ) {
        let userInfo = response.notification.request.content.userInfo
        // TODO: Remove print, integrate
        print("RemoteNotificationManager didReceive: \(userInfo)")
        completionHandler()
    }

    // This method is called when user already in the app and notification arrived
    func userNotificationCenter(
        _ center: UNUserNotificationCenter,
        willPresent notification: UNNotification,
        withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void
    ) {
        // TODO: Remove print, integrate completionHandler
        print("RemoteNotificationManager willPresent: \(notification.request.content.userInfo)")
        completionHandler(.banner)
    }
}

// MARK: - Firebase MessagingDelegate

extension AppDelegate: MessagingDelegate {

    // This fcmToken will be used for device specific notification from Firebase
    func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {
        // TODO: Remove print in integration
        print("APNS TOKEN \(Messaging.messaging().apnsToken)")
        if let fcmToken = fcmToken {
            print("RemoteNotificationManager fcm from api token: \(fcmToken)")
        }
    }
}

My question is what’s wrong with having a separate class like RemoteNotificationManager?

Latest articles

spot_imgspot_img

Related articles

Leave a reply

Please enter your comment!
Please enter your name here

spot_imgspot_img