Notificationcenter Issue on Swift 3

NotificationCenter issue on Swift 3

Swift 3 & 4

Swift 3, and now Swift 4, have replaced many "stringly-typed" APIs with struct "wrapper types", as is the case with NotificationCenter. Notifications are now identified by a struct Notfication.Name rather than by String. For more details see the now legacy Migrating to Swift 3 guide

Swift 2.2 usage:

// Define identifier
let notificationIdentifier: String = "NotificationIdentifier"

// Register to receive notification
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(YourClassName.methodOfReceivedNotification(_:)), name: notificationIdentifier, object: nil)

// Post a notification
NSNotificationCenter.defaultCenter().postNotificationName(notificationIdentifier, object: nil)

Swift 3 & 4 usage:

// Define identifier
let notificationName = Notification.Name("NotificationIdentifier")

// Register to receive notification
NotificationCenter.default.addObserver(self, selector: #selector(YourClassName.methodOfReceivedNotification), name: notificationName, object: nil)

// Post notification
NotificationCenter.default.post(name: notificationName, object: nil)

// Stop listening notification
NotificationCenter.default.removeObserver(self, name: notificationName, object: nil)

All of the system notification types are now defined as static constants on Notification.Name; i.e. .UIApplicationDidFinishLaunching, .UITextFieldTextDidChange, etc.

You can extend Notification.Name with your own custom notifications in order to stay consistent with the system notifications:

// Definition:
extension Notification.Name {
static let yourCustomNotificationName = Notification.Name("yourCustomNotificationName")
}

// Usage:
NotificationCenter.default.post(name: .yourCustomNotificationName, object: nil)

Swift 4.2 usage:

Same as Swift 4, except now system notifications names are part of UIApplication. So in order to stay consistent with the system notifications you can extend UIApplication with your own custom notifications instead of Notification.Name :

// Definition:
UIApplication {
public static let yourCustomNotificationName = Notification.Name("yourCustomNotificationName")
}

// Usage:
NotificationCenter.default.post(name: UIApplication.yourCustomNotificationName, object: nil)

NotificationCenter Crash in Swift 3

Your issue is with your loadEntries(search:) method. It's not a valid signature. The selector used with Notification Center must either have no parameters or just one parameter. And if you have one parameter, that parameter will be the Notification object, not the notification name.

Your loadEntries needs to be:

func loadEntries(_ notification: NSNotification) {
// Optional check of the name
if notification.name == .preferenceNotification {
}
}

And the selector would need to be:

#selector(loadEntries(_:)) // or #selector(loadEntries)

NotificationCenter swift3 Can't observe post

Add your observers like following:

NotificationCenter.default.addObserver(self, selector: #selector(updateUx), name: NSNotification.Name("Notification1"), object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(updateUx), name: NSNotification.Name("Notification2"), object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(updateUx), name: NSNotification.Name("Notification3"), object: nil)

And you are good to go.


EDIT: Full source code (This project has a UIButton on view and the @IBAction is connected to it in storyboard. On tapping that button, all 3 notifications will get posted. The log is supposed to get printed thrice in console)

class ViewController: UIViewController {

override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
NotificationCenter.default.addObserver(self, selector: #selector(updateUx), name: NSNotification.Name("Notification1"), object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(updateUx), name: NSNotification.Name("Notification2"), object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(updateUx), name: NSNotification.Name("Notification3"), object: nil)
}

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

@IBAction func abc (_ sender: UIButton) {
NotificationCenter.default.post(name:NSNotification.Name("Notification1"), object: nil)
NotificationCenter.default.post(name:NSNotification.Name("Notification2"), object: nil)
NotificationCenter.default.post(name:NSNotification.Name("Notification3"), object: nil)
}

func updateUx(){
print("received...")
}
}

NotificationCenter not working in didSelectRowAt in iOS Swift 3

The selector for your observer is wrong. Your notification observer method takes parameter, you have not specified that while adding observer for that method in the selector parameter. The fact that your project is compiling means there must be another method with the same name but with no parameters.

Change to:

override func viewDidLoad() {
............
............

NotificationCenter.default.addObserver(self,selector: #selector(thisistestHandler(notification:)),name: NSNotification.Name(rawValue:"thisIsTestNotif"),object: nil)
}

@objc func thisistestHandler(notification:Notification) {

}

Swift 3, NotificationCenter observer missing posted Notification

You are passing the NotificationPipelinesProtocol object to addObserver. This means that you will only receive notifications posted by that object. If you want to receive notifications of the specified name posted by any object then you should pass nil:

NotificationCenter.default.addObserver(self,
selector: #selector(Notifications.didReceiveNotificationCompletion(_:)),
name: notification.completionNotificationName,
object: nil)

How to pass data using NotificationCenter in swift 3.0 and NSNotificationCenter in swift 2.0?

Swift 2.0

Pass info using userInfo which is a optional Dictionary of type [NSObject : AnyObject]?

  let imageDataDict:[String: UIImage] = ["image": image]

// Post a notification
NSNotificationCenter.defaultCenter().postNotificationName(notificationName, object: nil, userInfo: imageDataDict)

// Register to receive notification in your class
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(self.showSpinningWheel(_:)), name: notificationName, object: nil)

// handle notification
func showSpinningWheel(notification: NSNotification) {

if let image = notification.userInfo?["image"] as? UIImage {
// do something with your image
}
}

Swift 3.0, 4.0, 5.0 version and above

The userInfo now takes [AnyHashable: Any]? as an argument, which we provide as a dictionary literal in Swift

  let imageDataDict:[String: UIImage] = ["image": image]

// post a notification
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "notificationName"), object: nil, userInfo: imageDataDict)
// `default` is now a property, not a method call

// Register to receive notification in your class
NotificationCenter.default.addObserver(self, selector: #selector(self.showSpinningWheel(_:)), name: NSNotification.Name(rawValue: "notificationName"), object: nil)

// handle notification
// For swift 4.0 and above put @objc attribute in front of function Definition
func showSpinningWheel(_ notification: NSNotification) {

if let image = notification.userInfo?["image"] as? UIImage {
// do something with your image
}
}

NOTE: Notification “names” are no longer strings, but are of type Notification.Name, hence why we are using NSNotification.Name(rawValue: "notificationName") and we can extend Notification.Name with our own custom notifications.

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

// and post notification like this
NotificationCenter.default.post(name: .myNotification, object: nil)

NotificationCenter migrating swift 3 to swift 4.2 problem

You are making things too complicated than it should be...

With this code, Xcode 10 will show you the right fix-it suggestion.

fileprivate func observeKeyboardNotifications() {

NotificationCenter.default.addObserver(self, selector: #selector(keyboardShow),
name: UIKeyboardWillShowNotification, object: nil)

}

My Xcode 10 has fixed it as:

fileprivate func observeKeyboardNotifications() {

NotificationCenter.default.addObserver(self, selector: #selector(keyboardShow),
name: UIResponder.keyboardWillShowNotification, object: nil)

}


Related Topics



Leave a reply



Submit