Rectangle 27 37

Swift 3.0 in Xcode 8

Swift 3.0 has 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. See the Migrating to Swift 3 guide.

// 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)
// 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)
Notification.Name
.UIDeviceBatteryLevelDidChange
.UIApplicationDidFinishLaunching
.UITextFieldTextDidChange

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)

ios - NSNotificationCenter addObserver in Swift - Stack Overflow

ios swift nsnotificationcenter
Rectangle 27 36

Swift 3.0 in Xcode 8

Swift 3.0 has 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. See the Migrating to Swift 3 guide.

// 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)
// 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)
Notification.Name
.UIDeviceBatteryLevelDidChange
.UIApplicationDidFinishLaunching
.UITextFieldTextDidChange

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)

ios - NSNotificationCenter addObserver in Swift - Stack Overflow

ios swift nsnotificationcenter
Rectangle 27 33

A nice way of doing this is to use the addObserver(forName:object:queue:using:) method rather than the addObserver(_:selector:name:object:) method that is often used from Objective-C code. The advantage of the first variant is that you don't have to use the @objc attribute on your method:

func batteryLevelChanged(notification: Notification) {
        // do something useful with this information
    }

    let observer = NotificationCenter.default.addObserver(
        forName: NSNotification.Name.UIDeviceBatteryLevelDidChange,
        object: nil, queue: nil,
        using: batteryLevelChanged)

and you can even just use a closure instead of a method if you want:

let observer = NotificationCenter.default.addObserver(
        forName: NSNotification.Name.UIDeviceBatteryLevelDidChange,
        object: nil, queue: nil) { _ in print("") }

You can use the returned value to stop listening for the notification later:

NotificationCenter.default.removeObserver(observer)

There used to be another advantage in using this method, which was that it doesn't require you to use selector strings which couldn't be statically checked by the compiler and so were fragile to breaking if the method is renamed, but Swift 2.2 and later include #selector expressions that fix that problem.

This is great! For completeness I would just like to see unregistering example too. It is quite different then the addObserver(_:selector:name:object:) way of unregistering. You have to keep the object returned by addObserverForName(_:object:queue:usingBlock:) and pass it to removeObserver:

This needs updating to include de-registration of the objected returned by addObserverForName(_:object:queue:usingBlock:).

This is a much better answer than connor's or Renish's (both above at time of this comment) because it gets around having to use the Obj-C #selector methods. The result is much more Swift-y and more correct, IMO. Thanks!

Remember, if you use this in, say, a UIViewController and refer to self in that closure, you need to use [weak self] or you'll have a reference cycle and the memory leak.

ios - NSNotificationCenter addObserver in Swift - Stack Overflow

ios swift nsnotificationcenter
Rectangle 27 32

A nice way of doing this is to use the addObserver(forName:object:queue:using:) method rather than the addObserver(_:selector:name:object:) method that is often used from Objective-C code. The advantage of the first variant is that you don't have to use the @objc attribute on your method:

func batteryLevelChanged(notification: Notification) {
        // do something useful with this information
    }

    let observer = NotificationCenter.default.addObserver(
        forName: NSNotification.Name.UIDeviceBatteryLevelDidChange,
        object: nil, queue: nil,
        using: batteryLevelChanged)

and you can even just use a closure instead of a method if you want:

let observer = NotificationCenter.default.addObserver(
        forName: NSNotification.Name.UIDeviceBatteryLevelDidChange,
        object: nil, queue: nil) { _ in print("") }

You can use the returned value to stop listening for the notification later:

NotificationCenter.default.removeObserver(observer)

There used to be another advantage in using this method, which was that it doesn't require you to use selector strings which couldn't be statically checked by the compiler and so were fragile to breaking if the method is renamed, but Swift 2.2 and later include #selector expressions that fix that problem.

This is great! For completeness I would just like to see unregistering example too. It is quite different then the addObserver(_:selector:name:object:) way of unregistering. You have to keep the object returned by addObserverForName(_:object:queue:usingBlock:) and pass it to removeObserver:

This needs updating to include de-registration of the objected returned by addObserverForName(_:object:queue:usingBlock:).

This is a much better answer than connor's or Renish's (both above at time of this comment) because it gets around having to use the Obj-C #selector methods. The result is much more Swift-y and more correct, IMO. Thanks!

Remember, if you use this in, say, a UIViewController and refer to self in that closure, you need to use [weak self] or you'll have a reference cycle and the memory leak.

ios - NSNotificationCenter addObserver in Swift - Stack Overflow

ios swift nsnotificationcenter
Rectangle 27 574

@objc func methodOfReceivedNotification(notification: Notification){

}
NotificationCenter.default.post(name: Notification.Name("NotificationIdentifier"), object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(YourClassName.methodOfReceivedNotification(notification:)), name: Notification.Name("NotificationIdentifier"), object: nil)
deinit {
       NotificationCenter.default.removeObserver(self, name: Notification.Name("NotificationIdentifier"), object: nil)
    }
NSNotificationCenter.defaultCenter().postNotificationName("NotificationIdentifier", object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(YourClassName.methodOfReceivedNotification(_:)), name:"NotificationIdentifier", object: nil)
NSNotificationCenter.defaultCenter().postNotificationName("NotificationIdentifier", object: nil)
NSNotificationCenter.defaultCenter().removeObserver(self, name: "NotificationIdentifier", object: nil)
NSNotificationCenter.defaultCenter().removeObserver(self) // Remove from all notifications being observed
func methodOfReceivedNotification(notification: NSNotification){
    //Take Action on Notification
}

Annotate either the class or the target method with @objc

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

//Or

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

Be sure to annotate either the class or the target method with @objc.

@goofansu Are you sure? I reckon that you have to add it when it's a pure Swift class.

methodOFReceivedNotication must be either annotated with dynamic or be a member of a subclass of NSObject.

object 0x7fd68852d710 of class 'TestNotifications.MyObject' does not implement methodSignatureForSelector: -- trouble ahead
Unrecognized selector -[TestNotifications.MyObject methodOFReceivedNotication:]

ios - NSNotificationCenter addObserver in Swift - Stack Overflow

ios swift nsnotificationcenter
Rectangle 27 547

NotificationCenter.default.post(name: Notification.Name("NotificationIdentifier"), object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(YourClassName.methodOfReceivedNotification(notification:)), name: Notification.Name("NotificationIdentifier"), object: nil)
deinit {
       NotificationCenter.default.removeObserver(self, name: Notification.Name("NotificationIdentifier"), object: nil)
    }
NSNotificationCenter.defaultCenter().postNotificationName("NotificationIdentifier", object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(YourClassName.methodOfReceivedNotification(_:)), name:"NotificationIdentifier", object: nil)
NSNotificationCenter.defaultCenter().postNotificationName("NotificationIdentifier", object: nil)
NSNotificationCenter.defaultCenter().removeObserver(self, name: "NotificationIdentifier", object: nil)
NSNotificationCenter.defaultCenter().removeObserver(self) // Remove from all notifications being observed
func methodOfReceivedNotification(notification: NSNotification){
    //Take Action on Notification
}

Annotate either the class or the target method with @objc

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

//Or

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

Be sure to annotate either the class or the target method with @objc.

@goofansu Are you sure? I reckon that you have to add it when it's a pure Swift class.

methodOFReceivedNotication must be either annotated with dynamic or be a member of a subclass of NSObject.

object 0x7fd68852d710 of class 'TestNotifications.MyObject' does not implement methodSignatureForSelector: -- trouble ahead
Unrecognized selector -[TestNotifications.MyObject methodOFReceivedNotication:]

ios - NSNotificationCenter addObserver in Swift - Stack Overflow

ios swift nsnotificationcenter
Rectangle 27 357

It's the same as the Objective-C API, but uses Swift's syntax.

NSNotificationCenter.defaultCenter().addObserver(
    self,
    selector: #selector(batteryLevelChanged),
    name: UIDeviceBatteryLevelDidChangeNotification,
    object: nil)

Or in Swift 3:

NotificationCenter.default.addObserver(
    self,
    selector: #selector(self.batteryLevelChanged),
    name: .UIDeviceBatteryLevelDidChange,
    object: nil)

If your observer does not inherit from an Objective-C object, you must prefix your method with @objc in order to use it as a selector.

@objc func batteryLevelChanged(notification: NSNotification){     
    //do stuff
}

Thanks! I didn't know how to pass the selector name in Swift.

@BerryBlue, did the above solution work for you? I believe that you need to change "batteryLevelChanged" to "batteryLevelChanged:" if your function accepts the NSNotification as a parameter.

UIDeviceBatteryLevelDidChangeNotification

Be sure to annotate either the class or the target method with @objc.

ios - NSNotificationCenter addObserver in Swift - Stack Overflow

ios swift nsnotificationcenter
Rectangle 27 341

It's the same as the Objective-C API, but uses Swift's syntax.

NSNotificationCenter.defaultCenter().addObserver(
    self,
    selector: #selector(batteryLevelChanged),
    name: UIDeviceBatteryLevelDidChangeNotification,
    object: nil)

Or in Swift 3:

NotificationCenter.default.addObserver(
    self,
    selector: #selector(self.batteryLevelChanged),
    name: .UIDeviceBatteryLevelDidChange,
    object: nil)

If your observer does not inherit from an Objective-C object, you must prefix your method with @objc in order to use it as a selector.

@objc func batteryLevelChanged(notification: NSNotification){     
    //do stuff
}

Thanks! I didn't know how to pass the selector name in Swift.

@BerryBlue, did the above solution work for you? I believe that you need to change "batteryLevelChanged" to "batteryLevelChanged:" if your function accepts the NSNotification as a parameter.

UIDeviceBatteryLevelDidChangeNotification

Be sure to annotate either the class or the target method with @objc.

ios - NSNotificationCenter addObserver in Swift - Stack Overflow

ios swift nsnotificationcenter
Rectangle 27 6

You can also pass data using NotificationCentre in swift 3.0 and NSNotificationCenter in swift 2.0.

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

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
func showSpinningWheel(_ notification: NSNotification) {

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

ios - NSNotificationCenter addObserver in Swift - Stack Overflow

ios swift nsnotificationcenter
Rectangle 27 6

You can also pass data using NotificationCentre in swift 3.0 and NSNotificationCenter in swift 2.0.

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

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
func showSpinningWheel(_ notification: NSNotification) {

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

ios - NSNotificationCenter addObserver in Swift - Stack Overflow

ios swift nsnotificationcenter
Rectangle 27 2

I'm able to do one of the following to successfully use a selector - without annotating anything with @objc:

NSNotificationCenter.defaultCenter().addObserver(self,
    selector:"batteryLevelChanged:" as Selector,
    name:"UIDeviceBatteryLevelDidChangeNotification",
    object:nil)
let notificationSelector: Selector = "batteryLevelChanged:"

NSNotificationCenter.defaultCenter().addObserver(self,
    selector: notificationSelector,
    name:"UIDeviceBatteryLevelDidChangeNotification",
    object:nil)

My xcrun version shows Swift 1.2, and this works on Xcode 6.4 and Xcode 7 beta 2 (which I thought would be using Swift 2.0):

$xcrun swift --version

Apple Swift version 1.2 (swiftlang-602.0.53.1 clang-602.0.53)

You don't need to annotate with @objc if your observer class inherits from NSObject.

And you shouldn't need to explicitly cast a String to Selector either. :)

@alfvata: My observer class does not inherit from NSObject. It inherits from AnyObject, Swift-style. Explicitly casting the string to Selector is allowing me to avoid doing any of the other Objective-C-related workarounds.

I'm not sure I understand how that works. I removed the @objc annotation from the method in my non-NSObject observer class, added the as Selector casting to the String selector name, and when the notification fires the app crashes. My Swift version is exactly the same as yours.

@alfavata, I don't know what to tell you. I'm now on Xcode Beta 4, and it's still working. My project is totally Swift; there are no Objective-C components. Maybe that makes a difference. Maybe there's something different in the project settings. There are any number of possibilities! I'll say: as long as the @objc annotation works for you, and this way doesn't, then keep annotating!

ios - NSNotificationCenter addObserver in Swift - Stack Overflow

ios swift nsnotificationcenter
Rectangle 27 2

I'm able to do one of the following to successfully use a selector - without annotating anything with @objc:

NSNotificationCenter.defaultCenter().addObserver(self,
    selector:"batteryLevelChanged:" as Selector,
    name:"UIDeviceBatteryLevelDidChangeNotification",
    object:nil)
let notificationSelector: Selector = "batteryLevelChanged:"

NSNotificationCenter.defaultCenter().addObserver(self,
    selector: notificationSelector,
    name:"UIDeviceBatteryLevelDidChangeNotification",
    object:nil)

My xcrun version shows Swift 1.2, and this works on Xcode 6.4 and Xcode 7 beta 2 (which I thought would be using Swift 2.0):

$xcrun swift --version

Apple Swift version 1.2 (swiftlang-602.0.53.1 clang-602.0.53)

You don't need to annotate with @objc if your observer class inherits from NSObject.

And you shouldn't need to explicitly cast a String to Selector either. :)

@alfvata: My observer class does not inherit from NSObject. It inherits from AnyObject, Swift-style. Explicitly casting the string to Selector is allowing me to avoid doing any of the other Objective-C-related workarounds.

I'm not sure I understand how that works. I removed the @objc annotation from the method in my non-NSObject observer class, added the as Selector casting to the String selector name, and when the notification fires the app crashes. My Swift version is exactly the same as yours.

@alfavata, I don't know what to tell you. I'm now on Xcode Beta 4, and it's still working. My project is totally Swift; there are no Objective-C components. Maybe that makes a difference. Maybe there's something different in the project settings. There are any number of possibilities! I'll say: as long as the @objc annotation works for you, and this way doesn't, then keep annotating!

ios - NSNotificationCenter addObserver in Swift - Stack Overflow

ios swift nsnotificationcenter
Rectangle 27 2

deinit 
{
  NotificationCenter.default.removeObserver(self, name:NSNotification.Name(rawValue: "notify"), object: nil)

}

I believe you don't need this since iOS 9. It's done automatically.

ios - NSNotificationCenter addObserver in Swift - Stack Overflow

ios swift nsnotificationcenter
Rectangle 27 2

#selector
NSNotificationCenter
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(rotate), name: UIDeviceOrientationDidChangeNotification, object: nil)

ios - NSNotificationCenter addObserver in Swift - Stack Overflow

ios swift nsnotificationcenter
Rectangle 27 2

deinit 
{
  NotificationCenter.default.removeObserver(self, name:NSNotification.Name(rawValue: "notify"), object: nil)

}

I believe you don't need this since iOS 9. It's done automatically.

ios - NSNotificationCenter addObserver in Swift - Stack Overflow

ios swift nsnotificationcenter
Rectangle 27 2

#selector
NSNotificationCenter
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(rotate), name: UIDeviceOrientationDidChangeNotification, object: nil)

ios - NSNotificationCenter addObserver in Swift - Stack Overflow

ios swift nsnotificationcenter
Rectangle 27 1

//Add observer
NotificationCenter.default.addObserver(self, selector: #selector(batteryStateDidChange), name: NSNotification.Name.UIDeviceBatteryStateDidChange, object: nil)


 //Fired when battery level changes

 func batteryStateDidChange(notification: NSNotification){
        //perform manipulation here
    }

ios - NSNotificationCenter addObserver in Swift - Stack Overflow

ios swift nsnotificationcenter
Rectangle 27 1

//Add observer
NotificationCenter.default.addObserver(self, selector: #selector(batteryStateDidChange), name: NSNotification.Name.UIDeviceBatteryStateDidChange, object: nil)


 //Fired when battery level changes

 func batteryStateDidChange(notification: NSNotification){
        //perform manipulation here
    }

ios - NSNotificationCenter addObserver in Swift - Stack Overflow

ios swift nsnotificationcenter
Rectangle 27 0

in iOS9 you can use:

NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(YourViewControllerName.methodOFReceivedNotication), name: "NotificationIdentifier", object: nil)

ios - NSNotificationCenter addObserver in Swift while call a private m...

ios swift
Rectangle 27 0

In your code you are adding observer in the VC2 viewdidload and it will get called only after you call performsegue.So, till you call perform segue your notification has no observer. The solution is

@IBAction func sendNotfctn(sender: AnyObject)
{
 performSegueWithIdentifier("Go", sender: self)//Here I move to VC2. 
 NSNotificationCenter.defaultCenter().postNotificationName("MY NOTIFICATION", object: self)
}

in VC1

ios - NSNotificationCenter addobserver not calling the selector method...

ios swift nsnotificationcenter