Anand Gautam
Anand Gautam

Reputation: 2579

NotificationCenter is not working from AppDelegate in Swift iOS

I am facing a very stupid issue while using NotificationCenter.

Introduction: I am using Firebase notification in my App, so basically once any user will receive the notification we need to navigate user to the specific ViewController screen.

Here is my code:

@available(iOS 10, *)
extension AppDelegate: UNUserNotificationCenterDelegate {

    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {

        let userInfo = response.notification.request.content.userInfo

        if let paymentStatus = userInfo["message"] as? String {

            if paymentStatus == "SUCCESS"{

            // handle notification
            NotificationCenter.default.post(name: NSNotification.Name(rawValue: "PaymentSuccessfulNotification"), object: nil, userInfo: userInfo)
            }
        }

        completionHandler()
    }
}

ViewController.swift viewDidLoad method:

NotificationCenter.default.addObserver(self,selector: #selector(paymentSuccessfulNotificationReceived),
name: NSNotification.Name(rawValue: "PaymentSuccessfulNotification"), object: nil)

And declared this method as well:

@objc func paymentSuccessfulNotificationReceived(notification: NSNotification){

        DispatchQueue.main.async {

            // Navigate code
            let viewController = AppManager.VideoCallStoryBoard.instantiateViewController(withIdentifier:  "ViewController") as! ViewController
            self.navigationController?.pushViewController(viewController, animated: false)
        }

    }

Problem: When I am receiving the Firebase notification then my AppDelegate's userNotificationCenter: didReceive response: method is getting called. but my ViewController.swift class method is not getting invoked.

Please anyone help me on this. Thanks!

Note: Instead, if I will add my addObserver method to the ViewController class which I am setting up as window.rootViewController then everything is working fine. My method is getting called.

Upvotes: 2

Views: 1480

Answers (1)

CrackIt
CrackIt

Reputation: 684

I think this is totally wrong approach to use NotificationCenter because first you have to observe the notification then only you can post something. If the ViewController isn't in the memory it can not listen to anything. I hope you are getting my point. It's like saying hello to deaf person. Instead you should find the top ViewController in didReceive response method and navigate through using its navigation controller. You can use below function to find Top most ViewController.

extension UIApplication {

    /** To find top viewcontroller */
    class func topViewController(base: UIViewController? = UIApplication.shared.windows.first { $0.isKeyWindow }?.rootViewController) -> UIViewController? {
        if let nav = base as? UINavigationController {
            return topViewController(base: nav.visibleViewController)
        }
        if let tab = base as? UITabBarController {
            if let selected = tab.selectedViewController {
                return topViewController(base: selected)
            }
        }
        if let presented = base?.presentedViewController {
            return topViewController(base: presented)
        }
        return base
    }
}

The reason behind its working when making rootViewController because it's in memory before you post something.

Upvotes: 2

Related Questions