如何在 Swift 3.0中使用 NotificationCenter 传递数据,在 Swift 2.0中使用 NSNotificationCenter 传递数据?

我正在我的迅捷 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并将其包含在被调用的函数中呢?

159994 次浏览

Swift 2.0

使用 userInfo传递信息,userInfo[NSObject : AnyObject]?类型的可选 Dictionary

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

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”不再是字符串,而是 Notification 类型。名称,因此我们使用 NSNotification.Name(rawValue: "notificationName"),并且我们可以扩展 Notification。使用我们自己的自定义通知命名。

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


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

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

希望对你有帮助,谢谢

为了 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
}
}
}

这就是我实现它的方式。

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

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

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

迅捷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)
    

注意: 不要忘记删除观察者,当你不再需要它的时候。