ChatGPT解决这个技术问题 Extra ChatGPT

如何使用 swift 3.0 中的 NotificationCenter 和 swift 2.0 中的 NSNotificationCenter 传递数据?

我正在我的 swift ios 应用程序中实现 socket.io

目前在几个面板上,我正在监听服务器并等待传入消息。我通过调用每个面板中的 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 并将其包含在被调用的函数中?

使用用户信息的方法... NSNotificationCenter.defaultCenter().postNotificationName("hideSpinner", object: nil, userInfo: yourvalue)
嗯,好的,我如何在该通知上调用的函数中获取这个 yourValue(在 showSpinningWheel 中)?
notification.userinfo 一样使用 .userinfo

S
Sahil

斯威夫特 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、4.0、5.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)

S
Sachin Rasane

对于斯威夫特 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
            }
        }
 }

对于斯威夫特 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
            }
        }
 }

为我工作 Swift 4
D
DoesData

你好@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
            }
        }
 }

希望它有帮助。谢谢


应该是 notification.userinfo,而不是 notification.object
如果您从objective-c 类/通知接收对象/字典,则必须使用.object。如果您从 Swift 通知中接收对象,请使用 .userInfo。跟踪您的通知,如果它是 .object 或 .userInfo : func observerNotification(notification: NSNotification){ print("Notification Received :", notification) }
在发布到该通知键之前,请确保您是否在跨线程发送您在该键上设置了观察者。您可能更熟悉术语侦听器和事件。
W
WaliD

这就是在 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)

S
Shivam Parmar

这就是我实现它的方式。

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

W
WINSergey

Swift 5.5 与避免 #selector()

首先,声明名称:

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

接下来是添加观察者(注意队列):

// For example transferred data should implement protocol
protocol PrettyDelegate {
    func doSomethingAwesome()
}

// Here is the way how we can subscribe as observer
NotificationCenter.default.addObserver(forName: .prettyName, object: nil, queue: nil) { [weak self] notif in
    guard let self = self else { return } // Because self used more than once
    if let userInfo = notif.userInfo,
       let delegate = userInfo["pretty"] as? PrettyDelegate {
        self.delegate = delegate
    }
    
    self.makePretty() // Here we can do anything
}

最后,我们可以从另一个对象发布通知

// Here I'll illustrate how to pass optional value as userInfo
var userInfo: [AnyHashable : Any]?
if let prettyDelegate = self as? PrettyDelegate {
    userInfo = ["pretty": prettyDelegate]
}
NotificationCenter.default.post(name: .prettyName, object: nil, userInfo: userInfo)
    

注意:当您不再需要它时,不要忘记移除观察者。


M
Mohammad Muddasir

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