iosswiftnotificationcenter

How to readd a notification observer


So I have about four notification observers added in a particular view controller, but I want to remove one in particular if a condition is met and then add it back for a different condition. I was able to remove the particular observer but I have had trouble adding it back. the other ones work except the one a removed and added back and I know it's working cos when the VC loads and all the notification observers are added but then it stops working after adding it back. here's my code:


// registered the observer in ViewDIdAppear and this registers my bluetooth device and whenever i tap on the bluetooth device button this function gets called
NotificationCenter.default.addObserver(
    self, selector: #selector(Myclass.deviceTapped), name: Notification.Name("bluetoothRecievedNoticicationName"), object: nil)

// i removed the observer here 
 if condition == false {
          NotificationCenter.default.removeObserver(self, name:  Notification.Name("bluetoothRecievedNoticicationName"), object: nil)

}  

// and then use this to add it back again 
NotificationCenter.default.addObserver(
    self, selector: #selector(Myclass.deviceTapped), name:  Notification.Name("bluetoothRecievedNoticicationName"), object: nil)

// and after adding this ^ back the deviceTapped function doesn't get called anymore

Solution

  • The thing to do in these situations is prove to yourself that this does normally work. That way, you can track down what you are doing that prevents it from working.

    For example, perhaps self is going out of existence before any notifications have a chance to arrive...? Perhaps some other code, that you have not shown, is unregistering you again...? I've certainly experienced confusions like that! And they can be very hard to debug.

    But whatever the explanation, you need first to assure yourself that unregistering for a notification and then re-registering for it is not a problem.

    Here's a test app. It has three buttons: Register, Unregister, and Notify. Here's the code:

    let notif : Notification.Name = .init("howdy")
    @objc func gotNotified() {
        print("got notified")
    }
    @IBAction func doRegister(_ sender: Any) {
        NotificationCenter.default.addObserver(self, selector: #selector(gotNotified), name: notif, object: nil)
    }
    @IBAction func doUnregister(_ sender: Any) {
        NotificationCenter.default.removeObserver(self, name: notif, object: nil)
    }
    @IBAction func doNotify(_ sender: Any) {
        NotificationCenter.default.post(name: notif, object: nil)
    }
    

    So configure that with the buttons hooked up, and then:

    1. Tap Register.

    2. Tap Notify.

    3. Tap Unregister.

    4. Tap Notify.

    5. Tap Register.

    6. Tap Notify.

    You will see that on 2 and 6, but not 4, we print to the console to prove we were notified — just as you would expect.