Como passar dados usando NotificationCenter em swift 3.0 e NSNotificationCenter em swift 2.0?

122

Estou implementando socket.ioem meu aplicativo ios swift.

Atualmente em vários painéis estou ouvindo o servidor e aguardando mensagens recebidas. Estou fazendo isso chamando a getChatMessagefunção em cada painel:

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

No entanto, percebi que é uma abordagem errada e preciso mudá-la - agora quero começar a ouvir as mensagens recebidas apenas uma vez e quando chegar alguma mensagem - passe essa mensagem para qualquer painel que a ouvir.

Portanto, desejo passar a mensagem recebida pelo NSNotificationCenter. Até agora consegui passar a informação de que algo aconteceu, mas não passei os dados em si. Eu estava fazendo isso por:

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

então eu tive uma função chamada:

func showSpinningWheel(notification: NSNotification) {
}

e sempre que eu queria ligar, estava fazendo:

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

Então, como posso passar o objeto messageInfoe incluí-lo na função que é chamada?

user3766930
fonte
2
usar método com informações de usuário ...NSNotificationCenter.defaultCenter().postNotificationName("hideSpinner", object: nil, userInfo: yourvalue)
EI Captain v2.0
hm ok, e como posso buscar isso yourValuena função que é chamada nessa notificação (in showSpinningWheel)?
user3766930
usando .userinfocomo notification.userinfo
EI Captain v2.0

Respostas:

277

Swift 2.0

Passe informações usando o userInfoque é um Dicionário opcional do 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   
  }
 }

Versão Swift 3.0 e superior

O userInfo agora leva [AnyHashable: Any]? como um argumento, que fornecemos como um dicionário literal em 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: Os “nomes” de notificação não são mais strings, mas são do tipo Notification.Name, por isso estamos usando NSNotification.Name(rawValue:"notificationName")e podemos estender Notification.Name com nossas próprias notificações personalizadas.

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

// and post notification like this
NotificationCenter.default.post(name: .myNotification, object: nil)
Sahil
fonte
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
fonte
1
Trabalhou para mim Swift 4
Ravi,
20

Olá @sahil, atualizo sua resposta para o 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 seja útil. obrigado

Ilesh P
fonte
3
deve ser notification.userinfo, não notification.object
Pak Ho Cheung
1
Se você estiver recebendo objeto / dicionário da classe / notificação objetiva-c, deverá usar .object. Se você estiver recebendo um objeto da notificação do Swift, use .userInfo. Rastreie sua notificação se for .object ou .userInfo com: func observerNotification (notificação: NSNotification) {print ("Notificação recebida:", notificação)}
Doci de
Certifique-se de enviar através de threads que você configurou o observador nessa chave antes de postar nessa chave de notificação. Você pode estar mais familiarizado com os termos ouvinte e evento.
Aaron
2

é assim que eu o implemento.

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

No swift 4.2, usei o seguinte código para mostrar e ocultar o 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
fonte