NSNotificationCenter addObserver в Swift
Как добавить наблюдателя в Swift в Центр уведомлений по умолчанию? Я пытаюсь перенести эту строку кода, которая отправляет уведомление при изменении уровня заряда батареи.
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(batteryLevelChanged:) name:UIDeviceBatteryLevelDidChangeNotification object:nil];
11 ответов:
это то же самое, что Objective-C API, но использует синтаксис Swift.
NSNotificationCenter.defaultCenter().addObserver( self, selector: #selector(batteryLevelChanged), name: UIDeviceBatteryLevelDidChangeNotification, object: nil)
или в Swift 3:
NotificationCenter.default.addObserver( self, selector: #selector(self.batteryLevelChanged), name: .UIDeviceBatteryLevelDidChange, object: nil)
если ваш наблюдатель не наследует от объекта Objective-C, вы должны префикс вашего метода с
@objc
для того, чтобы использовать его в качестве селектора.@objc func batteryLevelChanged(notification: NSNotification){ //do stuff }
посмотреть Ссылка На Класс NSNotificationCenter,взаимодействие с API Objective-C
Swift 4.0 & Xcode 9.0+:
Отправить (Post) Уведомление:
NotificationCenter.default.post(name: Notification.Name("NotificationIdentifier"), object: nil)
или
NotificationCenter.default.post(name: Notification.Name("NotificationIdentifier"), object: nil, userInfo: ["Renish":"Dadhaniya"])
Получить (Получить) Уведомление:
NotificationCenter.default.addObserver(self, selector: #selector(self.methodOfReceivedNotification(notification:)), name: Notification.Name("NotificationIdentifier"), object: nil)
функция-метод обработчик полученного уведомления:
@objc func methodOfReceivedNotification(notification: Notification) {}
Swift 3.0 & Xcode 8.0+:
Отправить(Пост) Уведомление:
NotificationCenter.default.post(name: Notification.Name("NotificationIdentifier"), object: nil)
Получить (Получить) Уведомление:
NotificationCenter.default.addObserver(self, selector: #selector(YourClassName.methodOfReceivedNotification(notification:)), name: Notification.Name("NotificationIdentifier"), object: nil)
обработчик метода для полученного уведомления:
func methodOfReceivedNotification(notification: Notification) { // Take Action on Notification }
Удалить Уведомление:
deinit { NotificationCenter.default.removeObserver(self, name: Notification.Name("NotificationIdentifier"), object: nil) }
Swift 2.3 & Xcode 7:
Отправить (Post) Уведомление
NSNotificationCenter.defaultCenter().postNotificationName("NotificationIdentifier", object: nil)
Получить (Получить) Уведомление
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(YourClassName.methodOfReceivedNotification(_:)), name:"NotificationIdentifier", object: nil)
обработчик получено уведомление
func methodOfReceivedNotification(notification: NSNotification){ // Take Action on Notification }
для исторических версий Xcode...
Отправить (Post) Уведомление
NSNotificationCenter.defaultCenter().postNotificationName("NotificationIdentifier", object: nil)
Получить (Получить) Уведомление
NSNotificationCenter.defaultCenter().addObserver(self, selector: "methodOfReceivedNotification:", name:"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 }
аннотировать либо класс, либо целевой метод с помощью @objc
@objc private func methodOfReceivedNotification(notification: NSNotification) { // Take Action on Notification } // Or dynamic private func methodOfReceivedNotification(notification: NSNotification) { // Take Action on Notification }
Swift 3.0 в Xcode 8
Swift 3.0 заменил многие" строго типизированные " API на
struct
"типы обертки", как в случае с NotificationCenter. Уведомления теперь идентифицируются с помощьюstruct Notfication.Name
, а неString
. Смотрите переход на 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)
новый Swift 3.0 использование:
// 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
и т. д.вы можете продлить
Notification.Name
С вашими собственными пользовательскими уведомлениями, чтобы оставаться в соответствии с системными уведомлениями:// Definition: extension Notification.Name { static let yourCustomNotificationName = Notification.Name("yourCustomNotificationName") } // Usage: NotificationCenter.default.post(name: .yourCustomNotificationName, object: nil)
хороший способ сделать это-использовать
addObserver(forName:object:queue:using:)
метод, а неaddObserver(_:selector:name:object:)
метод, который часто используется из объективных-C код. Преимущество первого варианта заключается в том, что вам не нужно использовать@objc
атрибут вашего метода: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)
и вы даже можете просто использовать закрытие вместо метода, если вы хотите:
let observer = NotificationCenter.default.addObserver( forName: NSNotification.Name.UIDeviceBatteryLevelDidChange, object: nil, queue: nil) { _ in print("") }
вы можете использовать возвращенное значение, чтобы прекратить прослушивание уведомления позже:
NotificationCenter.default.removeObserver(observer)
в использовании этого метода было еще одно преимущество, которое заключалось в том, что он не требовал использования строк селектора, которые не могли быть статически проверены компилятором и поэтому были хрупкими для взлома, если метод переименован, но Swift 2.2 и позже включают
#selector
выражения чтобы исправить эту проблему.
объявить имя уведомления
extension Notification.Name { static let purchaseDidFinish = Notification.Name("purchaseDidFinish") }
вы можете добавить наблюдателя двумя способами:
используя
Selector
NotificationCenter.default.addObserver(self, selector: #selector(myFunction), name: .purchaseDidFinish, object: nil) @objc func myFunction(notificaiont: Notification) { print(notificaiont.object ?? "") //myObject print(notificaiont.userInfo ?? "") //[AnyHashable("key"): "Value"] }
или через
block
NotificationCenter.default.addObserver(forName: .purchaseDidFinish, object: nil, queue: nil) { [weak self] (notification) in guard let strongSelf = self else { return } strongSelf.myFunction(notificaiont: notification) } func myFunction(notificaiont: Notification) { print(notificaiont.object ?? "") //myObject print(notificaiont.userInfo ?? "") //[AnyHashable("key"): "Value"] }
разместить уведомление
NotificationCenter.default.post(name: .purchaseDidFinish, object: "myObject", userInfo: ["key": "Value"])
из iOS 9 и OS X 10.11. Это больше не является необходимым для NSNotificationCenter наблюдателя ООН-регистрируется при освободившему. подробнее
на
block
на основе реализации вам нужно сделать слабый-сильный танец, если вы хотите использоватьself
внутри блока. подробнее
передача данных с помощью NSNotificationCenter
вы также можете передавать данные с помощью NotificationCentre в swift 3.0 и NSNotificationCenter в swift 2.0.
Версия Swift 2.0
передать информацию с помощью сведений о пользователях, которая представляет собой дополнительный словарь типа [NSObject : какой-либо объект]?
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
в userInfo в настоящее время занимает [AnyHashable:любая]? в качестве аргумента, который мы приводим в качестве словарь литерал в 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 } }
источник передача данных с помощью NotificationCentre (swift 3.0) и NSNotificationCenter(swift 2.0)
Я могу выполните одно из следующих действий, чтобы успешно использовать селектор - без аннотирование чего-либо с помощью @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)
моя версия xcrun показывает Swift 1.2, и это работает на Xcode 6.4 и Xcode 7 beta 2 (который, как я думал, будет использовать Swift 2.0):
$xcrun swift --version Apple Swift version 1.2 (swiftlang-602.0.53.1 clang-602.0.53)
в swift 2.2-XCode 7.3 мы используем
#selector
наNSNotificationCenter
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(rotate), name: UIDeviceOrientationDidChangeNotification, object: nil)
мы должны удалить уведомление.
Ex.
deinit { NotificationCenter.default.removeObserver(self, name:NSNotification.Name(rawValue: "notify"), object: nil) }
в swift 3, Xcode 8.2: - проверка уровня заряда батареи
//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 }
NSNotificationCenter добавить синтаксис наблюдателя в Swift 4.0 на iOS 11
NotificationCenter.default.addObserver(self, selector: #selector(keyboardShow), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
Это для типа имени уведомления keyboardWillShow. Другой тип может быть выбран из существующих вариант
селектор имеет тип @objc func, который обрабатывает, как клавиатура покажет (это ваша пользовательская функция )