Swift 4 - Notification Center addObserver issue

47k Views Asked by At

I'm crashing and getting an unrecognized selector error every time a Notification arrives and the App tries to execute its associated method. Here's my code - which is in viewDidLoad:

let notificationCenter = NotificationCenter.default
notificationCenter.addObserver(self, selector: Selector(("sayHello")), name:NSNotification.Name(rawValue: "dataDownloadCompleted"), object: nil)

The sayHello() method is quite simple - looks like this:

func sayHello() {
    print("Hello")
}

I've verified that the Notification is posted successfully and that it arrives successfully - so that's not the issue. The crash happens when the App looks to act upon the arrival of the Notification - by executing the sayHello() method. It keeps giving me that unrecognized selector error.

Any ideas what I'm doing wrong? (By the way, this worked perfectly with Swift 3 & Xcode 8, but now with Swift 4 and Xcode 9 the syntax has changed [Xcode walked me through the necessary code fixes/updates] - but the crashes keep happening.)

3

There are 3 best solutions below

1
On BEST ANSWER

You can improve your code with these steps:

extension Notification.Name {
    static let dataDownloadCompleted = Notification.Name(
       rawValue: "dataDownloadCompleted")
}

And use it like this:

let notificationCenter = NotificationCenter.default
notificationCenter.addObserver(self,
                               selector: #selector(YourClass.sayHello),
                               name: .dataDownloadCompleted,
                               object: nil)

But as was already pointed out, issue is solved by changing to #selector

0
On

Swift 4.0 & Xcode 9.0+:

Send(Post) Notification:

NotificationCenter.default.post(name: Notification.Name("NotificationIdentifier"), object: nil)

OR

NotificationCenter.default.post(name: Notification.Name("NotificationIdentifier"), object: nil, userInfo: ["Renish":"Dadhaniya"])

Receive(Get) Notification:

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

Function-Method handler for received Notification:


@objc func methodOfReceivedNotification(notification: Notification) {}

Swift 3.0 & Xcode 8.0+:

Send(Post) Notification:


NotificationCenter.default.post(name: Notification.Name("NotificationIdentifier"), object: nil)

Receive(Get) Notification:


NotificationCenter.default.addObserver(self, selector: #selector(YourClassName.methodOfReceivedNotification(notification:)), name: Notification.Name("NotificationIdentifier"), object: nil)

Method handler for received Notification:

func methodOfReceivedNotification(notification: Notification) {
  // Take Action on Notification
}

Remove Notification:

deinit {
  NotificationCenter.default.removeObserver(self, name: Notification.Name("NotificationIdentifier"), object: nil)
}

Swift 2.3 & Xcode 7:

Send(Post) Notification

NSNotificationCenter.defaultCenter().postNotificationName("NotificationIdentifier", object: nil)

Receive(Get) Notification


NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(YourClassName.methodOfReceivedNotification(_:)), name:"NotificationIdentifier", object: nil)

Method handler for received Notification

func methodOfReceivedNotification(notification: NSNotification){
  // Take Action on Notification
}

Ref:https://medium.com/@javedmultani16/notification-in-swift-4-8b0db631f49d

1
On
Data Receiving - Add observer:

override func viewDidLoad() {
     super.viewDidLoad()
     NotificationCenter.default.addObserver(self, selector: #selector(yourfunction(notfication:)), name: .postNotifi, object: nil)
}

@objc func yourfunction(notfication: NSNotification) {
     print("xxx")
}

Sending Data - Post Notification:

override func viewWillDisappear(_ animated: Bool) {
      super.viewWillDisappear(animated)
      NotificationCenter.default.removeObserver(self, name: .postNotifi, object: nil)
}

extension Notification.Name {
      static let postNotifi = Notification.Name("postNotifi")
}