Notification observer called multiple times even though the observer is removed

Viewed 2570

When the app is in background mode or phone is in sleep state and a VoIp push is received the below function in AppDelagte directs the user (to the UserTableViewController in the app) and posts a notification.

A notification observer in viewDidLoad of the UserTableViewController observes the notification and calls the func simulateMyIncomingCallFromNotification.

I noticed that when I send a VoIP push the second time the func simulateMyIncomingCallFromNotification is called twice and on the third time, thrice and so on. How can I avoid multiple calls ?

Other SO answers, advised to remove the Notification observer, which I am doing even before setting one, as you can seen in the below extension, but this doesn't seem to solve my problem.

How could I resolve this issue ?

In AppDelegate:

func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, forType type: PKPushType) {

 let storyboard = UIStoryboard(name: "User", bundle: nil)

 VC = storyboard.instantiateViewController(withIdentifier: "UserTableViewController") as! UserTableViewController

 self.window = UIWindow(frame: UIScreen.main.bounds)
        self.window?.rootViewController = VC
        self.window?.makeKeyAndVisible()


NotificationCenter.default.post(name: Notification.Name("didReceiveIncomingVoipPush"), object: nil, userInfo: payloadDict)
}

In UserTableViewController

extension NotificationCenter {
    func setObserver(_ observer: AnyObject, selector: Selector, name: NSNotification.Name, object: AnyObject?) {
        print("NotificationCenter.default before: \(NotificationCenter.default)")
        NotificationCenter.default.removeObserver(observer, name: name, object: object)
        NotificationCenter.default.addObserver(observer, selector: selector, name: name, object: object)
        print("NotificationCenter.default after: \(NotificationCenter.default)")
    }
}

fun viewDidLoad(){

NotificationCenter.default.setObserver(self, selector: #selector(self.simulateMyIncomingCallFromNotification(notification:)), name: Notification.Name("didReceiveIncomingVoipPush"), object: nil)

}
3 Answers

Apple recommends that observers should be registered in viewWillAppear and unregistered in viewWillDissapear.

Can you try like this.

Getting multiple calls on notifications is probably the case that your controller is not being de-initialised and each time you are adding a new observer to new instance of that controller. What you can do:

Add breakpoint on that method and try print(self) and see the address of multiples calls.

or just add

 deinit() {
    print(self)
 }

and check whether that class is being deinitilized or not.

And if thats not the case you can try @Himanth solution.

In my case Notification is calling the number of time i'm appearing in same screen and which is caused to triggered same action X numberofTime i'm entered to screen. So I've removed Notification observer in viewWillDisappear which is actually worked and stopped the multiple time triggered action/methods in same screen.

Thanks to Himanth's answer i've figured it out

  • Swift4

addObserver

 override func viewDidLoad(){
       super.viewDidLoad()

      NotificationCenter.default.addObserver(self, selector: #selector(self.yourNotificationAction(notification:)), name: Notification.Name("yourNotificationName"), object: nil)

}

removeObserver when screen is disappear

 override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        
        NotificationCenter.default.removeObserver(self, name: Notification.Name("yourNotificationName"), object: nil)
      
    }
Related