Як передавати дані за допомогою 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і включити його у функцію, яка викликається?


2
метод використання з інформацією про користувача ...NSNotificationCenter.defaultCenter().postNotificationName("hideSpinner", object: nil, userInfo: yourvalue)
EI Captain v2.0

хм нормально, і як я можу отримати це yourValueу функції, яка викликається в цьому повідомленні (в showSpinningWheel)?
користувач3766930

використовуючи .userinfoяк notification.userinfo
EI Captain v2.0

Відповіді:


277

Швидкий 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 версії та вище

Тепер користувачInfo приймає [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
Працював для мене Свіфт 4
Раві

20

Привіт @sahil Я оновлюю вашу відповідь за швидкий 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
має бути сповіщення.userinfo, а не notification.object
Pak Ho Cheung

1
Якщо ви отримуєте об'єкт / словник з класу / сповіщення target-c, ви повинні використовувати .object. Якщо ви отримуєте об'єкт від повідомлення Swift, використовуйте .userInfo. Відстежуйте сповіщення, якщо воно є .object або .userInfo за допомогою: func observerNotification (сповіщення: NSNotification) {print ("Повідомлення отримано:", повідомлення)}
Doci

Переконайтеся, що ви надсилаєте через потоки, які ви налаштували для цього спостерігача, перш ніж опублікувати цей ключ сповіщення. Можливо, ви більше знайомі з умовами слухача та подіями.
Аарон

2

ось як я це реалізую.

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

0

У швидкому 4.2 я використав наступний код, щоб показати та приховати код за допомогою NSNotification

 @objc func keyboardWillShow(notification: NSNotification) {
    if let keyboardSize = (notification.userInfo? [UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
        let keyboardheight = keyboardSize.height
        print(keyboardheight)
    }
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.