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

122

Я использую socket.ioсвое быстрое приложение для 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и включить его в вызываемую функцию?

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

Ответы:

277

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)
Сахил
источник
46

Для 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
            }
        }
 }
Сачин Расане
источник
1
У меня работал Swift 4
Ravi
20

Привет @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
            }
        }
 }

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

Илеш П
источник
3
должно быть notification.userinfo, а не notification.object
Пак Хо Чунг
1
Если вы получаете объект / словарь из класса / уведомления objective-c, вы должны использовать .object. Если вы получаете объект из уведомления Swift, используйте .userInfo. Отслеживайте свое уведомление, если это .object или .userInfo, с помощью: func ObserverNotification (notification: NSNotification) {print («Уведомление получено:», уведомление)}
Doci
Убедитесь, что если вы отправляете по потокам, что вы настроили наблюдателя для этого ключа, прежде чем отправлять сообщение на этот ключ уведомления. Возможно, вам лучше знакомы термины слушатель и событие.
Аарон
2

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

let dictionary = self.convertStringToDictionary(responceString)            
     NotificationCenter.default.post(name: NSNotification.Name(rawValue: "SOCKET_UPDATE"), object: dictionary)
Нитин
источник
0

В 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)
    }
}
Мохаммад Муддасир
источник