¿Cómo pasar datos usando NotificationCenter en swift 3.0 y NSNotificationCenter en swift 2.0?

122

Estoy implementando socket.ioen mi aplicación ios rápida.

Actualmente en varios paneles estoy escuchando el servidor y espero mensajes entrantes. Lo hago llamando a la getChatMessagefunción en cada panel:

func getChatMessage(){
    SocketIOManager.sharedInstance.getChatMessage { (messageInfo) -> Void in
        dispatch_async(dispatch_get_main_queue(), { () -> Void in
            //do sth depending on which panel user is
        })
    }
}

Sin embargo, noté que es un enfoque incorrecto y necesito cambiarlo; ahora quiero comenzar a escuchar los mensajes entrantes solo una vez y cuando llegue cualquier mensaje, pase este mensaje a cualquier panel que lo escuche.

Así que quiero pasar el mensaje entrante a través del NSNotificationCenter. Hasta ahora pude pasar la información de que sucedió algo, pero no pasar los datos en sí. Estaba haciendo eso por:

NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(ViewController.showSpinningWheel(_:)), name: showSpinner, object: nil)

entonces tuve una función llamada:

func showSpinningWheel(notification: NSNotification) {
}

y cada vez que quería llamarlo estaba haciendo:

NSNotificationCenter.defaultCenter().postNotificationName(hideSpinner, object: self)

Entonces, ¿cómo puedo pasar el objeto messageInfoe incluirlo en la función que se llama?

usuario3766930
fuente
2
use el método con userinfo ...NSNotificationCenter.defaultCenter().postNotificationName("hideSpinner", object: nil, userInfo: yourvalue)
EI Captain v2.0
hm ok, y ¿cómo puedo obtener esto yourValueen la función que se llama en esa notificación (en showSpinningWheel)?
user3766930
usando .userinfolike notification.userinfo
EI Captain v2.0

Respuestas:

277

Swift 2.0

¿Pasar información usando userInfocuál 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 y superior

UserInfo ahora toma [AnyHashable: Any]? como argumento, que proporcionamos como literal de diccionario 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
 // 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   
  }
 }

NOTA: Los “nombres” de notificación ya no son cadenas, sino de tipo Notification.Name, por lo que estamos usando NSNotification.Name(rawValue:"notificationName")Notification.Name y podemos extenderlo con nuestras propias notificaciones personalizadas.

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

// and post notification like this
NotificationCenter.default.post(name: .myNotification, object: nil)
Sahil
fuente
46

Para Swift 3

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) {
        print(notification.userInfo ?? "")
        if let dict = notification.userInfo as NSDictionary? {
            if let id = dict["image"] as? UIImage{
                // do something with your image
            }
        }
 }

Para Swift 4

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
 @objc func showSpinningWheel(_ notification: NSNotification) {
        print(notification.userInfo ?? "")
        if let dict = notification.userInfo as NSDictionary? {
            if let id = dict["image"] as? UIImage{
                // do something with your image
            }
        }
 }
Sachin Rasane
fuente
1
Trabajó para mí Swift 4
Ravi
20

Hola @sahil actualizo tu respuesta para swift 3

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) {
        print(notification.userInfo ?? "")
        if let dict = notification.userInfo as NSDictionary? {
            if let id = dict["image"] as? UIImage{
                // do something with your image
            }
        }
 }

Espero que sea de ayuda. Gracias

Ilesh P
fuente
3
debe ser notification.userinfo, no notification.object
Pak Ho Cheung
1
Si está recibiendo un objeto / diccionario de la clase / notificación de objetivo-c, debe usar .object. Si está recibiendo un objeto de la notificación Swift, utilice .userInfo. Rastree su notificación si es .object o .userInfo con: func observerNotification (notificación: NSNotification) {print ("Notificación recibida:", notificación)}
Doci
Asegúrese de que si está enviando subprocesos, configure el observador en esa clave antes de publicar en esa clave de notificación. Es posible que esté más familiarizado con los términos oyente y evento.
Aaron
2

así es como lo implemento.

let dictionary = self.convertStringToDictionary(responceString)            
     NotificationCenter.default.post(name: NSNotification.Name(rawValue: "SOCKET_UPDATE"), object: dictionary)
Nitin
fuente
0

En swift 4.2 utilicé el siguiente código para mostrar y ocultar código usando NSNotification

 @objc func keyboardWillShow(notification: NSNotification) {
    if let keyboardSize = (notification.userInfo? [UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
        let keyboardheight = keyboardSize.height
        print(keyboardheight)
    }
}
Mohammad Muddasir
fuente