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
Download Array of Images as Byte Array and Convert to Images
What Happens When Testflight App Expire
How to Size a Uitextview to Its Content
Adjust Uilabel Height Depending on the Text
How to Rotate a Uiimage 90 Degrees
What Are Different Types of Notifications in iOS and How to Configure Them Correctly
Change User Agent in Uiwebview
Difference Between Observedobject and Stateobject in Swiftui
How to Change Uipickerview Height
How to Center Horizontally Uicollectionview Cells
Nsattributedstring Click Event in Uilabel Using Swift
How to Do Base64 Encoding on Ios
How to Apply a Perspective Transform to a Uiview
Array Extension to Remove Object by Value