Comment transmettre des données à l'aide de NotificationCenter dans Swift 3.0 et NSNotificationCenter dans Swift 2.0?

122

J'implémente socket.iodans mon application iOS rapide.

Actuellement sur plusieurs panneaux, j'écoute le serveur et j'attends les messages entrants. Je le fais en appelant la getChatMessagefonction dans chaque panneau:

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

Cependant, j'ai remarqué que c'est une mauvaise approche et que je dois la changer - maintenant je veux commencer à écouter les messages entrants une seule fois et quand un message arrive - transmettez ce message à n'importe quel panneau qui l'écoute.

Je veux donc faire passer le message entrant via NSNotificationCenter. Jusqu'à présent, j'ai pu transmettre les informations indiquant que quelque chose s'était passé, mais pas les données elles-mêmes. Je faisais cela en:

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

puis j'ai eu une fonction appelée:

func showSpinningWheel(notification: NSNotification) {
}

et chaque fois que je voulais l'appeler, je faisais:

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

Alors, comment puis-je passer l'objet messageInfoet l'inclure dans la fonction qui est appelée?

utilisateur3766930
la source
2
utiliser la méthode avec userinfo ...NSNotificationCenter.defaultCenter().postNotificationName("hideSpinner", object: nil, userInfo: yourvalue)
EI Captain v2.0
hm ok, et comment puis-je récupérer cela yourValuedans la fonction qui est appelée sur cette notification (in showSpinningWheel)?
user3766930
en utilisant .userinfocomme notification.userinfo
EI Captain v2.0

Réponses:

277

Swift 2.0

Transmettre les informations en utilisant userInfoquel est un dictionnaire facultatif de type [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   
  }
 }

Version Swift 3.0 et supérieure

Le userInfo prend maintenant [AnyHashable: Any]? comme argument, que nous fournissons comme littéral de dictionnaire dans 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   
  }
 }

REMARQUE: les «noms» de notification ne sont plus des chaînes, mais sont de type Notification.Name, c'est pourquoi nous utilisons NSNotification.Name(rawValue:"notificationName")et pouvons étendre Notification.Name avec nos propres notifications personnalisées.

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

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

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

Pour 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
la source
1
A travaillé pour moi Swift 4
Ravi
20

Bonjour @sahil, je mets à jour votre réponse pour 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
            }
        }
 }

J'espère que c'est utile. Merci

Ilesh P
la source
3
devrait être notification.userinfo, pas notification.object
Pak Ho Cheung
1
Si vous recevez un objet / dictionnaire de la classe / notification objective-c, vous devez utiliser .object. Si vous recevez un objet de la notification Swift, utilisez .userInfo. Suivez votre notification s'il s'agit de .object ou .userInfo avec: func observerNotification (notification: NSNotification) {print ("Notification Received:", notification)}
Doci
Assurez-vous si vous envoyez à travers les threads que vous avez configuré l'observateur sur cette clé avant de publier sur cette clé de notification. Vous connaissez peut-être mieux les termes auditeur et événement.
Aaron
2

c'est ainsi que je le mets en œuvre.

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

Dans swift 4.2, j'ai utilisé le code suivant pour afficher et masquer le code à l'aide de NSNotification

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