Как передать данные с помощью NotificationCenter в Swift 3.0 и NSNotificationCenter в Swift 2.0?

Я использую socket.io в моем приложении Swift для iOS.

Сейчас на нескольких панелях я слушаю сервер и жду входящих сообщений. Я делаю это, вызывая функцию getChatMessage на каждой панели:

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

Однако я заметил, что это неправильный подход, и мне нужно его изменить - теперь я хочу начать прослушивать входящие сообщения только один раз, и когда приходит какое-либо сообщение, передайте это сообщение любой панели, которая его слушает.

Итак, я хочу передать входящее сообщение через NSNotificationCenter. Пока я мог передать информацию о том, что что-то произошло, но не передавал сами данные. Я делал это:

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

тогда у меня была функция под названием:

func showSpinningWheel(notification: NSNotification) {
}

и каждый раз, когда я хотел это назвать, я делал:

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

Итак, как я могу передать объект messageInfo и включить его в вызываемую функцию?


person user3766930    schedule 28.04.2016    source источник
comment
использовать метод с информацией о пользователе ... NSNotificationCenter.defaultCenter().postNotificationName("hideSpinner", object: nil, userInfo: yourvalue)   -  person EI Captain v2.0    schedule 28.04.2016
comment
хм, хорошо, и как я могу получить это yourValue в функции, которая вызывается при этом уведомлении (в showSpinningWheel)?   -  person user3766930    schedule 28.04.2016
comment
используя .userinfo как notification.userinfo   -  person EI Captain v2.0    schedule 28.04.2016


Ответы (6)


Swift 2.0

Передать информацию с помощью userInfo, который является необязательным словарем типа [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   
  }
 }

Версия Swift 3.0 и выше

UserInfo теперь принимает [AnyHashable: Any]? в качестве аргумента, который мы предоставляем как словарный литерал в 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   
  }
 }

ПРИМЕЧАНИЕ. «Имена» уведомлений больше не являются строками, а имеют тип Notification.Name, поэтому мы используем NSNotification.Name(rawValue:"notificationName") и можем расширить Notification.Name с помощью наших собственных настраиваемых уведомлений.

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

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

Для 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
            }
        }
 }

Для 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
            }
        }
 }
person Sachin Rasane    schedule 31.07.2018
comment
У меня работал Swift 4 - person Ravi; 17.10.2018

Привет @sahil, обновляю твой ответ для 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
            }
        }
 }

Надеюсь, это поможет. Спасибо

person Ilesh P    schedule 07.06.2017
comment
должно быть notification.userinfo, а не notification.object - person Pak Ho Cheung; 12.07.2017
comment
Если вы получаете объект / словарь из класса / уведомления objective-c, вы должны использовать .object. Если вы получаете объект из уведомления Swift, используйте .userInfo. Отслеживайте свое уведомление, если это .object или .userInfo, с помощью: func ObserverNotification (notification: NSNotification) {print (Уведомление получено:, уведомление)} - person Egzon P.; 18.04.2018
comment
Убедитесь, что если вы отправляете через потоки, что вы настроили наблюдателя для этого ключа, прежде чем отправлять сообщение на этот ключ уведомления. Возможно, вы более знакомы с терминами слушатель и событие. - person Aaron; 28.05.2018

вот как я это реализую.

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

Это то, что у меня сработало в Swift 5

NotificationCenter.default.addObserver(self,
                                       selector: #selector(handleMassage),
                                       name: Notification.Name("NotificationName"),
                                       object: nil)

Метод, обрабатывающий уведомление:

    @objc func handleMassage(notification: NSNotification) {
    if let dict = notification.object as? NSDictionary {
        if let myMessage = dict["myMessage"] as? String{
            myLabel.text = myMessage
        }
    }
}

Я разместил это так:

let dic = ["myMessage": "testing"]
NotificationCenter.default.post(name: Notification.Name("NotificationName"), object: dic)
person WaliD    schedule 21.03.2021

В Swift 4.2 я использовал следующий код для отображения и скрытия кода с помощью NSNotification.

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