Jak przekazać dane za pomocą NotificationCenter w Swift 3.0 i NSNotificationCenter w Swift 2.0?

122

Wdrażam socket.iow mojej szybkiej aplikacji na iOS.

Obecnie na kilku panelach słucham serwera i czekam na przychodzące wiadomości. Robię to, wywołując getChatMessagefunkcję w każdym panelu:

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

Zauważyłem jednak, że jest to złe podejście i muszę to zmienić - teraz chcę zacząć nasłuchiwać przychodzących wiadomości tylko raz, a gdy nadejdzie jakakolwiek wiadomość - przekaż tę wiadomość do dowolnego panelu, który jej nasłuchuje.

Dlatego chcę przekazać przychodzącą wiadomość przez NSNotificationCenter. Do tej pory udało mi się przekazać informację, że coś się stało, ale nie przekazałem samych danych. Robiłem to poprzez:

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

wtedy miałem funkcję o nazwie:

func showSpinningWheel(notification: NSNotification) {
}

i za każdym razem, gdy chciałem to nazwać, robiłem:

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

Jak więc mogę przekazać obiekt messageInfoi dołączyć go do wywoływanej funkcji?

user3766930
źródło
2
użyj metody z informacjami o użytkowniku ...NSNotificationCenter.defaultCenter().postNotificationName("hideSpinner", object: nil, userInfo: yourvalue)
EI Captain v2.0
hm ok, i jak mogę to pobrać yourValuew funkcji, która jest wywoływana w tym powiadomieniu (w showSpinningWheel)?
user3766930
używając .userinfonotification.userinfo
czegoś

Odpowiedzi:

277

Swift 2.0

Przekaż informacje, używając userInfoopcjonalnego słownika typu [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   
  }
 }

Wersja Swift 3.0 i nowsze

Informacje o użytkowniku zajmują teraz [AnyHashable: Any]? jako argument, który podajemy jako literał słownikowy w języku 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   
  }
 }

UWAGA: „Nazwy” powiadomień nie są już ciągami, ale są typu Notification.Name, stąd dlaczego używamy NSNotification.Name(rawValue:"notificationName")i możemy rozszerzyć Notification.Name o nasze własne niestandardowe powiadomienia.

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

// and post notification like this
NotificationCenter.default.post(name: .myNotification, object: nil)
Sahil
źródło
46

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

Dla 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
źródło
1
Pracował dla mnie Swift 4
Ravi
20

Cześć @sahil, zaktualizuję twoją odpowiedź na 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
            }
        }
 }

Mam nadzieję, że to pomocne. Dzięki

Ilesh P
źródło
3
powinny być notification.userinfo nie notification.object
Pak Ho Cheung
1
Jeśli otrzymujesz obiekt / słownik z klasy / powiadomienia objective-c, musisz użyć .object. Jeśli otrzymujesz obiekt z powiadomienia Swift, użyj .userInfo. Śledź powiadomienie, jeśli jest to .object lub .userInfo, za pomocą: func observerNotification (notification: NSNotification) {print ("Notification Received:", notification)}
Doci
Upewnij się, że wysyłasz między wątkami, że ustawiłeś obserwatora na tym kluczu przed wysłaniem wiadomości do tego klucza powiadomienia. Możesz być bardziej zaznajomiony z terminami słuchacz i zdarzenie.
Aaron
2

tak to wdrażam.

let dictionary = self.convertStringToDictionary(responceString)            
     NotificationCenter.default.post(name: NSNotification.Name(rawValue: "SOCKET_UPDATE"), object: dictionary)
Nitin
źródło
0

W swift 4.2 użyłem następującego kodu, aby pokazać i ukryć kod za pomocą NSNotification

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