Nsnotificationcenter Addobserver in Swift

NSNotificationCenter addObserver in Swift

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

Swift 4.2 & Swift 5:

NotificationCenter.default.addObserver(
self,
selector: #selector(self.batteryLevelChanged),
name: UIDevice.batteryLevelDidChangeNotification,
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 private func batteryLevelChanged(notification: NSNotification){     
//do stuff using the userInfo property of the notification object
}

See NSNotificationCenter Class Reference, Interacting with Objective-C APIs

Swift 4 - Notification Center addObserver issue

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

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)

NSNotificationCenter addobserver not calling the selector method in SWIFT

You sent the notification before the second view controller could add itself as observer.

If the goal is to send data to the next ViewController, I suggest using prepareForSegue.

You mentioned that your second ViewController is embedded in a Navigation Controller. That's ok. You can use something like this:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

if segue.identifier == "YOUR_IDENTIFIER" {

// The destination ViewController is a NavigationController.
// The top ViewController of the NavigationController is your target.
// In this example we are just setting a String in the destination ViewController.
if let navigationController = segue.destinationViewController as? UINavigationController {

if let myTargetViewController = navigationController.topViewController as? MyTargetViewController {
myTargetViewController.myStringVar = "My string value."
}
}
}
}

You can also be fancy and write the same thing like this:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

if let navigationController = segue.destinationViewController as? UINavigationController,
myTargetViewController = navigationController.topViewController as? MyTargetViewController
where segue.identifier == "YOUR_IDENTIFIER" {

myTargetViewController.myStringVar = "My string value."
}
}

As explained here.

Cheers!

NSNotification addObserver in two ViewControllers Swift

Kind of piggybacking off of the answer from Phillip: If it is absolutely necessary that the second view controller listen to the NSNotification event, then the second view controller can be instantiated from the storyboard and held in memory by the first view controller until it needs to be displayed. In this case, the second view controller should subscribe to the notification event upon initialization.

How to set addObserver in SwiftUI?

This worked for me

   let NC = NotificationCenter.default



self.NC.addObserver(forName: .NEVPNStatusDidChange, object: nil, queue: nil,
using: self.VPNDidChangeStatus)


func VPNDidChangeStatus(_ notification: Notification) {


}

NSNotificationCenter: Add observer but only if not registered to observe? Possible to query observing status for an object?

Unfortunately no, there is not. Just like KVO, notification center doesn't provide an API that lets us check whether an object (self in this case) has already been registered as an observer or not.

How to removeObserver in Swift 5 using addObserver closure method

Set your observer object to current view controller.

From apple doc.s, object is

The object whose notifications the observer wants to receive; that is,
only notifications sent by this sender are delivered to the observer.

NotificationCenter.default.addObserver(forName: UIApplication.didBecomeActiveNotification,
object: self,
queue: nil) { [weak self] notification in
guard let self = self else { return }
self.loadWeather(notification.object)
}

Removing observer from NotificationCenter

deinit {
NotificationCenter.default.removeObserver(self)
}

ANOTHER WAY

You can also make copy of Notification Observer object and remove it from NotificationCenter in deinit.

let notificationCenter = NotificationCenter.default
var loadWeatherObserver: NSObjectProtocol?

override func viewDidLoad() {
super.viewDidLoad()
loadWeatherObserver = notificationCenter.addObserver(forName: UIApplication.didBecomeActiveNotification,
object: nil,
queue: nil) { [weak self] notification in
guard let self = self else { return }
self.loadWeather(notification.object)
}
}

deinit {
if (loadWeatherObserver != nil) {
notificationCenter.removeObserver(loadWeatherObserver!)
}
}


Related Topics



Leave a reply



Submit