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)
How to pass object with NSNotificationCenter
You'll have to use the "userInfo" variant and pass a NSDictionary object that contains the messageTotal integer:
NSDictionary* userInfo = @{@"total": @(messageTotal)};
NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
[nc postNotificationName:@"eRXReceived" object:self userInfo:userInfo];
On the receiving end you can access the userInfo dictionary as follows:
-(void) receiveTestNotification:(NSNotification*)notification
{
if ([notification.name isEqualToString:@"TestNotification"])
{
NSDictionary* userInfo = notification.userInfo;
NSNumber* total = (NSNumber*)userInfo[@"total"];
NSLog (@"Successfully received test notification! %i", total.intValue);
}
}
Swift local notification, show a viewcontroller and pass data
eg. if you have two viewcontroller. fristVC and secondVC
you want to try some event in secondVC and you want to effect in firstVC right.
so first of all you have set this two line code in firstVc
NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: “NotifinationName”), object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(StnNotificationExist(_:)), name: NSNotification.Name(rawValue: "NotifinationName"), object: nil)
and this func also in FirstVc
@objc func StnNotificationExist(_ notification:NSNotification)
{
if let objId = notification.userInfo![“objId”] as? Int
{
// Your code here
print(objId)
}
}
In secondVC set this code in click event
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "NotifinationName"), object: nil, userInfo: ["objId":1] )
if you want to show firstVC with update you want to set push or pop viewcontroller after this line of code
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
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)
How to pass parameter to selector in swift?
It is simpler to use block, like
private var _observer: Any! // unsubscribed automatically on deinit
func addObserver(_ scrollView: UIScrollView) {
_observer = NotificationCenter.default.addObserver(forName: name,
object: nil, queue: nil) { notification in
// ... just use scrollView here
}
}
Related Topics
How to Convert an Nsstring Value to Nsdata
Didselectrowatindexpath Not Working, Swift 3
How to Run App in Simulator: Xcode Beta 6 iOS 8
Get a List of All Contacts on Ios
Do I Need to Disable Nslog Before Release Application
Send Post Request Using Nsurlsession
How to Debug iOS 8 Extensions With Nslog
Uilabel - Auto-Size Label to Fit Text
iOS 7 Status Bar with Phonegap
Change Color of Certain Pixels in a Uiimage
What Kind of Leaks Does Automatic Reference Counting in Objective-C Not Prevent or Minimize
How to Correctly Linearize Depth in Opengl Es in Ios
Uiscrollview Pauses Nstimer Until Scrolling Finishes
Storyboard Doesn't Contain a View Controller With Identifier
Check For Internet Connection Availability in Swift
Uinavigationbar Custom Back Button Without Title