observer notification example ios swift nsnotificationcenter

notification - observer ios swift



NSNotificationCenter addObserver en Swift (11)

¿Cómo agregar un observador en Swift al centro de notificaciones predeterminado? Estoy tratando de portar esta línea de código que envía una notificación cuando cambia el nivel de la batería.

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(batteryLevelChanged:) name:UIDeviceBatteryLevelDidChangeNotification object:nil];


Swift 3.0 en Xcode 8

Swift 3.0 ha reemplazado muchas API "de tipo estricto" con "tipos de envoltura" struct , como es el caso de NotificationCenter. Las notificaciones ahora se identifican por una struct Notfication.Name lugar de por String . Consulte la guía Migración a Swift 3 .

Uso anterior :

// 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)

Nuevo uso de 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)

Todos los tipos de notificación del sistema ahora están definidos como constantes estáticas en Notification.Name ; es decir .UIDeviceBatteryLevelDidChange , .UIApplicationDidFinishLaunching , .UITextFieldTextDidChange , etc.

Puede extender Notification.Name con sus propias notificaciones personalizadas para mantener la coherencia con las notificaciones del sistema:

// Definition: extension Notification.Name { static let yourCustomNotificationName = Notification.Name("yourCustomNotificationName") } // Usage: NotificationCenter.default.post(name: .yourCustomNotificationName, object: nil)


Swift 4.0 y Xcode 9.0+:

Enviar (Publicar) Notificación:

NotificationCenter.default.post(name: Notification.Name("NotificationIdentifier"), object: nil)

O

NotificationCenter.default.post(name: Notification.Name("NotificationIdentifier"), object: nil, userInfo: ["Renish":"Dadhaniya"])

Recibir (Obtener) Notificación:

NotificationCenter.default.addObserver(self, selector: #selector(self.methodOfReceivedNotification(notification:)), name: Notification.Name("NotificationIdentifier"), object: nil)

Controlador de función-método para la notificación recibida:

@objc func methodOfReceivedNotification(notification: Notification) {}

Swift 3.0 y Xcode 8.0+:

Enviar (Publicar) Notificación:

NotificationCenter.default.post(name: Notification.Name("NotificationIdentifier"), object: nil)

Recibir (Obtener) Notificación:

NotificationCenter.default.addObserver(self, selector: #selector(YourClassName.methodOfReceivedNotification(notification:)), name: Notification.Name("NotificationIdentifier"), object: nil)

Controlador de método para la notificación recibida:

func methodOfReceivedNotification(notification: Notification) { // Take Action on Notification }

Eliminar notificación:

deinit { NotificationCenter.default.removeObserver(self, name: Notification.Name("NotificationIdentifier"), object: nil) }

Swift 2.3 y Xcode 7:

Enviar (Publicar) Notificación

NSNotificationCenter.defaultCenter().postNotificationName("NotificationIdentifier", object: nil)

Recibir (Obtener) Notificación

NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(YourClassName.methodOfReceivedNotification(_:)), name:"NotificationIdentifier", object: nil)

Controlador de método para la notificación recibida

func methodOfReceivedNotification(notification: NSNotification){ // Take Action on Notification }

Para versiones históricas de Xcode ...

Enviar (Publicar) Notificación

NSNotificationCenter.defaultCenter().postNotificationName("NotificationIdentifier", object: nil)

Recibir (Obtener) Notificación

NSNotificationCenter.defaultCenter().addObserver(self, selector: "methodOfReceivedNotification:", name:"NotificationIdentifier", object: nil)

Eliminar notificación

NSNotificationCenter.defaultCenter().removeObserver(self, name: "NotificationIdentifier", object: nil) NSNotificationCenter.defaultCenter().removeObserver(self) // Remove from all notifications being observed

Controlador de método para la notificación recibida

func methodOfReceivedNotification(notification: NSNotification) { // Take Action on Notification }

Anote ya sea la clase o el método de destino con @objc

@objc private func methodOfReceivedNotification(notification: NSNotification) { // Take Action on Notification } // Or dynamic private func methodOfReceivedNotification(notification: NSNotification) { // Take Action on Notification }


  1. Declara un nombre de notificación

    extension Notification.Name { static let purchaseDidFinish = Notification.Name("purchaseDidFinish") }

  2. Puedes agregar observador de dos maneras:

    Usando 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"] }

    o usando 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"] }

  3. Publique su notificación

    NotificationCenter.default.post(name: .purchaseDidFinish, object: "myObject", userInfo: ["key": "Value"])

desde iOS 9 y OS X 10.11. Ya no es necesario que un observador de NSNotificationCenter se desregistre a sí mismo cuando se lo desasigna. más información

Para una implementación basada en block , necesitas hacer un baile débil y fuerte si quieres utilizar el self dentro del bloque. más información


Debemos eliminar la notificación también.

Ex.

deinit { NotificationCenter.default.removeObserver(self, name:NSNotification.Name(rawValue: "notify"), object: nil) }


En swift 2.2 - XCode 7.3, usamos #selector para NSNotificationCenter

NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(rotate), name: UIDeviceOrientationDidChangeNotification, object: nil)


Es igual que la API de Objective-C, pero usa la sintaxis de Swift.

NSNotificationCenter.defaultCenter().addObserver( self, selector: #selector(batteryLevelChanged), name: UIDeviceBatteryLevelDidChangeNotification, object: nil)

O en Swift 3:

NotificationCenter.default.addObserver( self, selector: #selector(self.batteryLevelChanged), name: .UIDeviceBatteryLevelDidChange, object: nil)

Si su observador no hereda de un objeto Objective-C, debe prefijar su método con @objc para usarlo como selector.

@objc func batteryLevelChanged(notification: NSNotification){ //do stuff }

Ver referencia de clase NSNotificationCenter , Interactuar con las API de Objective-C


Soy capaz de hacer una de las siguientes acciones para usar un selector con éxito, sin anotar nada con @objc:

NSNotificationCenter.defaultCenter().addObserver(self, selector:"batteryLevelChanged:" as Selector, name:"UIDeviceBatteryLevelDidChangeNotification", object:nil)

O

let notificationSelector: Selector = "batteryLevelChanged:" NSNotificationCenter.defaultCenter().addObserver(self, selector: notificationSelector, name:"UIDeviceBatteryLevelDidChangeNotification", object:nil)

Mi versión xcrun muestra Swift 1.2, y esto funciona en Xcode 6.4 y Xcode 7 beta 2 (que pensé que estaría usando Swift 2.0):

$xcrun swift --version Apple Swift version 1.2 (swiftlang-602.0.53.1 clang-602.0.53)


Una buena manera de hacer esto es usar el addObserver(forName:object:queue:using:) lugar del método addObserver(_:selector:name:object:) que se usa a menudo desde el código Objective-C. La ventaja de la primera variante es que no tiene que usar el atributo @objc en su método:

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)

e incluso puedes usar un cierre en lugar de un método si quieres:

let observer = NotificationCenter.default.addObserver( forName: NSNotification.Name.UIDeviceBatteryLevelDidChange, object: nil, queue: nil) { _ in print("🔋") }

Puede usar el valor devuelto para dejar de escuchar la notificación más tarde:

NotificationCenter.default.removeObserver(observer)

Solía ​​haber otra ventaja en el uso de este método, que era que no requiere que uses cadenas de selección que el compilador no pudo verificar de forma estática y que, por lo tanto, eran frágiles para romperlas si se cambia el nombre del método, pero Swift 2.2 y Más tarde incluya #selector expresiones #selector que solucionan ese problema.


En Swift 3, Xcode 8.2: - Comprobar el nivel de estado de la batería

//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 agrega sintaxis de observador en Swift 4.0 para iOS 11

NotificationCenter.default.addObserver(self, selector: #selector(keyboardShow), name: NSNotification.Name.UIKeyboardWillShow, object: nil)

Esto es para el tipo de nombre de notificación keyboardWillShow. Otro tipo se puede seleccionar de la opción disponible

el Selector es de tipo @objc func que controla cómo se mostrará el teclado (esta es su función de usuario)


Pasar datos utilizando NSNotificationCenter

También puede pasar datos usando NotificationCentre en swift 3.0 y NSNotificationCenter en swift 2.0.

Versión Swift 2.0

Pase información usando userInfo, que es un diccionario opcional de tipo [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 } }

Versión Swift 3.0

El userInfo ahora toma [AnyHashable: Any]? como un argumento, que proporcionamos como un diccionario literal en 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 } }

Datos de paso de origen utilizando NotificationCentre (swift 3.0) y NSNotificationCenter (swift 2.0)