iosswiftnsnotificationcenterremote-notifications

How to get Notificationcenter data from didFinishLaunchingWithOptions on swift 4


I'm working on an app that receives data from a remote notification, I'm trying to pass that data from didFinishLaunchingWithOptions to my ViewController using Notificationcenter when opening the app through tapping on the notification using launchOptions. The problem is that the observer on my viewDidAppear is not getting any data.

This is my code on the didFinishLaunchingWithOptions method:

func application(_ application: UIApplication,
                     didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {


    if let remoteNotification = launchOptions?[.remoteNotification] as?  [AnyHashable : Any] { 

             let nameSchool = remoteNotification["name_school" as! String]
              NotificationCenter.default.post(name: Notification.Name.nameSchool, object: nameSchool)

                }
    }

And the observer in the viewDidAppear method:

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)


NotificationCenter.default.addObserver(forName: Notification.Name.nameSchool, object: nil, queue: OperationQueue.main) { (nameSchool) in


            let schoolName = nameSchool.object as! String 

            self.messagePopup(message: "Data received")

        }
}

Solution

  • Since your application(,didFinishLaunchingWithOptions:) will be called before the viewDidAppear (as per your comment), then you will have to temporarily store the result you get from the function until your code can retrieve it later.

    @UIApplicationMain
    class AppDelegate: UIResponder, UIApplicationDelegate {
        var remoteNotificationAtLaunch: [AnyHashable: Any]?
        func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
            self.remoteNotificationAtLaunch = launchOptions?[.remoteNotification] as?  [AnyHashable : Any]
        }
    
        ...
    }
    

    Obviously keep the part you already have in your AppDelegate that generates the post to NotificationCenter when a remote notification is received. Then in your view controller, update your viewDidAppear...

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
    
        observeNotifications()
        checkForNotificationAtLaunch()
    }
    
    private func observeNotifications() {
        NotificationCenter.default.addObserver(forName: Notification.Name.nameSchool, object: nil, queue: OperationQueue.main) { (nameSchool) in
            let schoolName = nameSchool.object as! String
            self.processNotification(schoolName: schoolName)
        }
    }
    
    private func checkForNotificationAtLaunch() {
        if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
            if let notificationAtLaunch = appDelegate.remoteNotificationAtLaunch,
                let schoolName = notificationAtLaunch["name_school"] as? String {
                processNotification(schoolName: schoolName)
            }
        }
    }
    
    private func processNotification(schoolName: String) {
        self.messagePopup(message: "data received")
        // do something with schoolName....
    }