Ryan B.
Ryan B.

Reputation: 99

NS Notification Observer not being removed

I am working to detect screenshots in my app, here is the problem..

override func viewDidAppear(_ animated: Bool) {

    let mainQueue = OperationQueue.main
        NotificationCenter.default.addObserver(forName: NSNotification.Name.UIApplicationUserDidTakeScreenshot,
                                           object: nil,
                                           queue: mainQueue) { notification in
                                           print("SCREENSHOT TAKEN")

        }

    }
override func viewDidDisappear(_ animated: Bool) {
    NotificationCenter.default.removeObserver(self)
}

The observer is working fine, however it doesn't remove the observer, and then I can get tons of repeat listeners. I am attempting to understand the documentation, but I don't understand :/

Thanks!

Upvotes: 0

Views: 365

Answers (2)

Mukesh
Mukesh

Reputation: 2902

You can store the observer in a private variable and then remove it in your method like:

private var screenshotObserver: Any?

override func viewDidAppear(_ animated: Bool) {

    if screenshotObserver == nil {
        let mainQueue = OperationQueue.main
        screenshotObserver = NotificationCenter.default.addObserver(forName: NSNotification.Name.UIApplicationUserDidTakeScreenshot, object: nil, queue: mainQueue) { notification in
            print("SCREENSHOT TAKEN")
        }
    }
}

override func viewDidDisappear(_ animated: Bool) {

    if screenshotObserver != nil {
        NotificationCenter.default.removeObserver(screenshotObserver)
        screenshotObserver = nil
    }
}

Upvotes: 1

Jake
Jake

Reputation: 13753

Do not add the observer in viewDidAppear. Do it in viewDidLoad. viewDidAppear is potentially called multiple times, which means you might register for the UIApplicationUserDidTakeScreenshot notification multiple times.

Also, you do not need to unregister (removeObserver) in iOS9+. And if you're running on a version of iOS less than 9, I would suggest unregistering in deinit rather than viewDidDisappear.

override func viewDidLoad() {
    super.viewDidLoad()    

    let mainQueue = OperationQueue.main
    NotificationCenter.default.addObserver(forName: NSNotification.Name.UIApplicationUserDidTakeScreenshot, 
                object: nil, 
                queue: mainQueue) { notification in
        print("SCREENSHOT TAKEN")
    }
}

Upvotes: 1

Related Questions