Reputation: 2579
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
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