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
How to Send Post Parameters in Swift
Decode Base-64 Encoded Png in an Nsstring
Itsappusesnonexemptencryption Export Compliance While Internal Testing
Xcode Suddenly Stopped Running Project on Hardware: "Could Not Launch Xxx.App: .. No Such File.."
Take a Picture on iPhone Without Showing Controls
How to Detect Whether Custom Keyboard Is Activated from the Keyboard's Container App
Uibutton in Cell in Collection View Not Receiving Touch Up Inside Event
Check If User Is Logged into Icloud? Swift/Ios
How to Set Image in Tabbar Not Tint Color in iOS
Dashed Line Border Around Uiview
Paging Uiscrollview in Increments Smaller Than Frame Size
Add Shadow on Uiview Using Swift 3
Upload Image to the PHP Server from iOS