简体   繁体   中英

How to call notificationCenter whenever changes made in object in iOS Swift?

I am trying to achieve when the object update, Notificationcenter Post Message should trigger and receive at notification observer. But In my case notification post is in one controller and observer in another controller.

Here my code for a notification post from webViewController:

  if let jsonData = jsonString.data(using: .utf8) {
              do {
                let decoder = JSONDecoder()
                let mainObject = try decoder.decode(DynamicTabsModel.self, from: jsonData)

                print("tab model:::", mainObject)


                let dataDict:[AnyObject] = mainObject.tabInfo.tabList as [AnyObject]

                print("data object for tab", dataDict)


                NotificationCenter.default.post(name: Notification.Name("updateParentViewController"), object: mainObject)



              } catch {

                print(error.localizedDescription)

              }
            }

Here is the code for CreateCardViewController where I receive notification observer:

 NotificationCenter.default.addObserver(self, selector: #selector(self.updateParentViewController(_:)), name: Notification.Name(rawValue: "updateParentViewController"), object: nil)


   @objc func updateParentViewController(_ notification: NSNotification){


    if let receivedData = notification.object as? DynamicTabsModel {
    //use received data
        print("recieved back data:::", receivedData)

        for d in receivedData.tabInfo.tabList {

            print(d.label )
            self.tabMenuAry.append(d.label)


        }
        initCarbonKitTab()

        NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: "updateParentViewController"), object: nil)

        print("tab menu array::", self.tabMenuAry)


    }

}

My question is whenever the object model changes occur it should trigger the notification post method and it should receive the observer.

I have tried calling notification observer in viewdidload, viewdidappear, and viewwillappear. Nothing received.

Any help much appreciated pls...

Make sure your view controller has registered the observer. Sharing my code that is working fine. I have added observer in viewDidLoad. You can call fetchDate in other ViewController to pass the flow in this observer.

import Foundation
import UIKit
// MARK: - Observers

class MyViewController: UIViewController {
    override func viewDidLoad() {
        addObservers()
    }
    deinit {
        removeObservers()
    }
    @objc func notificationAction() {

    }
}

// MARK:- APIHandler
extension MyViewController {
    func fetchData() {
        // Call API when you get success response, post notification
        // NotificationCenter.default.post(name: NSNotification.Name(rawValue: NOTIFICATION_NAME.MY_NOTIFICATION), object: nil)
    }
}
extension MyViewController {
    func addObservers(){
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(notificationAction),
            name: NSNotification.Name(rawValue: NOTIFICATION_NAME.MY_NOTIFICATION) ,
            object: nil
        )
    }
    func removeObservers(){
        NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue:NOTIFICATION_NAME.MY_NOTIFICATION), object: nil)
    }
}

enum NOTIFICATION_NAME{
    static let MY_NOTIFICATION = "myNotification"
}

Is your viewcontroller an observer for that notification?

If not:

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

@objc func myactionWhenReceivePost() {

}

Edit after answer update:

When you add an observer if you register the object parameter it needs to be equal to the object sent posting the notification. It's like the Notification.Name , if it's not equal you won't receive any notification.

In addition: change your action's parameter from NSNotification to Notification since I think you're using Swift 5.0

If you want to pass data use userInfo that takes [AnyHashable:Any]? as input:

NotificationCenter.default.post(name: NSNotification.Name(rawValue: "updateParentViewController"), object: nil, userInfo: yourDictionary)

and in your action:

@objc func myactionWhenReceivePost(_ notification: Notification) {
      guard let myObject = notification.userInfo?["myObject"] as? MyObject else {return }

}

Here you go , as you already know how to register and unregister for notifications, lets get the custom userInfo from the notification

first post the notification with custom userInfo:

let customUserInfo: [AnyHashable: Any] = ["value": YOUR_CUSTOM_OBJECT]
NotificationCenter.default.post(name: .myNotificationName, object: nil, userInfo: customUserInfo)

Now when u want to catch this notification and need that info use this in receiver controller

@objc func onNotificationCatched(notification:NSNotification) {
    let userInfo:Dictionary<String, YOUR_CUSTOM_OBJECT > = notification.userInfo as! Dictionary<String, YOUR_CUSTOM_OBJECT>
    let value = userInfo["value"]! as YOUR_CUSTOM_OBJECT
    print(value)

}

in viewDidLoad of receiver controller use this

NotificationCenter.default.addObserver(self, selector: #selector(onNotificationCatched(notification:)), name: .myNotificationName, object: nil)

for ease of using NSNotifications Name , make an extension

extension NSNotification.Name {

static let myNotificationName = NSNotification.Name(rawValue: "My-Custom-Notification_String-Name")

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM