Come passare i dati utilizzando NotificationCenter in swift 3.0 e NSNotificationCenter in swift 2.0?


122

Sto implementando socket.ionella mia app iOS rapida.

Attualmente su più pannelli sto ascoltando il server e aspetto i messaggi in arrivo. Lo faccio chiamando la getChatMessagefunzione in ogni pannello:

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

Tuttavia ho notato che è un approccio sbagliato e ho bisogno di cambiarlo - ora voglio iniziare ad ascoltare i messaggi in arrivo solo una volta e quando arriva un messaggio - passa questo messaggio a qualsiasi pannello che lo ascolta.

Quindi voglio passare il messaggio in arrivo tramite NSNotificationCenter. Finora sono stato in grado di trasmettere l'informazione che è successo qualcosa, ma non di trasmettere i dati stessi. Lo stavo facendo:

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

poi ho avuto una funzione chiamata:

func showSpinningWheel(notification: NSNotification) {
}

e ogni volta che volevo chiamarlo stavo facendo:

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

Quindi come posso passare l'oggetto messageInfoe includerlo nella funzione che viene chiamata?


2
usa il metodo con info utente ...NSNotificationCenter.defaultCenter().postNotificationName("hideSpinner", object: nil, userInfo: yourvalue)
EI Captain v2.0

hm ok, e come posso recuperarlo yourValuenella funzione che viene chiamata su quella notifica (in showSpinningWheel)?
user3766930

usando .userinfocome notification.userinfo
EI Captain v2.0

Risposte:


277

Swift 2.0

Passare le informazioni utilizzando userInfoche è un dizionario opzionale di 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   
  }
 }

Versione Swift 3.0 e successive

UserInfo ora accetta [AnyHashable: Any]? come argomento, che forniamo come dizionario letterale 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   
  }
 }

NOTA: i "nomi" di notifica non sono più stringhe, ma sono di tipo Notification.Name, ecco perché stiamo usando NSNotification.Name(rawValue:"notificationName")e possiamo estendere Notification.Name con le nostre notifiche personalizzate.

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

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

46

Per 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
            }
        }
 }

Per 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
            }
        }
 }

1
Ha funzionato per me Swift 4
Ravi

20

Ciao @sahil, aggiorno la tua risposta per 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
            }
        }
 }

Spero sia utile. Grazie


3
dovrebbe essere notification.userinfo, non notification.object
Pak Ho Cheung

1
Se stai ricevendo un oggetto / dizionario da una notifica / classe object-c devi usare .object. Se ricevi un oggetto dalla notifica Swift, usa .userInfo. Tiene traccia della notifica se è .object o .userInfo con: func observerNotification (notification: NSNotification) {print ("Notification Received:", notification)}
Doci

Assicurati di aver impostato l'osservatore su quella chiave, se stai inviando attraverso thread, prima di postare su quella chiave di notifica. Potresti avere più familiarità con i termini ascoltatore ed evento.
Aaron

2

questo è come lo implemento.

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

0

In swift 4.2 ho usato il seguente codice per mostrare e nascondere il codice usando NSNotification

 @objc func keyboardWillShow(notification: NSNotification) {
    if let keyboardSize = (notification.userInfo? [UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
        let keyboardheight = keyboardSize.height
        print(keyboardheight)
    }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.