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?


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)

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

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


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)

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)
    }
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.