SpaceX
SpaceX

Reputation: 2890

Notification observer called multiple times even though the observer is removed

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)

}

Upvotes: 3

Views: 3437

Answers (3)

steveSarsawa
steveSarsawa

Reputation: 1679

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)
      
    }

Upvotes: 2

ankit
ankit

Reputation: 3647

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.

Upvotes: 2

Himanth
Himanth

Reputation: 2446

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

Can you try like this.

Upvotes: 10

Related Questions