Swift 的 NotificationCenter 帮助 - 如何使用 addObserver?

NotificationCenter help for Swift - how to use addObserver?

提问人:Darren Gates 提问时间:5/4/2023 最后编辑:HangarRashDarren Gates 更新时间:5/14/2023 访问量:58

问:

我有一个通知中心调用,如下所示,我正在尝试为它创建一个观察器,它只是调用同一个 Swift 文件中的函数:

NotificationCenter.default.post(
    name: Notification.Name(rawValue: "JSON"), 
    object: [ "json" : "[email protected]" ])
NotificationCenter.default.addObserver(self, 
    selector: #selector(receiveJsNotification(_:)), 
    name: NSNotification.Name ("JSON"), object: nil)

然后在我的 Swift 文件中,我有:

@objc
func receiveJsNotification(_ notification: Notification) {
   print("received notification");
   // how do I retrieve [email protected] value?
}

但是,“收到的通知”永远不会被打印出来,即使“post”和“addObserver”行(我在同一类的不同函数中都有)肯定会被执行(print 语句显示)。

我的 Swift 构建没有错误。我使用的是 Xcode 14.2

我做错了什么?另外,如何检索“[email protected]”值?

iOS Swift 通知中心

评论

0赞 HangarRash 5/4/2023
在(及时)调用之前发出的调用是否在调用 ?addObserverpost
0赞 Darren Gates 5/4/2023
是的,绝对
0赞 Paulw11 5/4/2023
要回答您的第二个问题,您提供的数据位于notification.userInfo

答:

0赞 Duncan C 5/4/2023 #1

我不确定为什么你的代码不起作用。我刚刚使用默认的 iPhone 应用程序模板(使用 Storyboards)敲出了一个示例项目

下面是 ViewController 类的代码:

import UIKit

class ViewController: UIViewController {
    
    let testNotification = NSNotification.Name(rawValue: "testNotification")

    @IBAction func sendNotification(_ sender: Any) {
        print("In \(#function)")
        NotificationCenter.default.post(name: testNotification, object: nil)
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        NotificationCenter.default.addObserver(self, selector: #selector(notifificationReceived), name: testNotification, object: nil)
    }
    
    @objc func notifificationReceived(_ theNotificaiton: Notification) {
        print("Notification received")
    }
}

当我将该代码的 IBAction 连接到按钮、运行应用程序并点击该按钮时,我看到控制台上出现一条“收到通知”消息,告诉我它有效

显然,这是一个非常幼稚的例子,它向侦听它的同一对象(视图控制器)发送通知,但它证明了通知中心是有效的。

评论

0赞 Duncan C 5/4/2023
请参阅我的答案的更新。我提供了观察通知的工作示例代码,然后在收到通知时将其发布并记录到控制台。
0赞 Ghulam Mustafa 5/4/2023 #2

为了使您的代码正常工作,请在 userinfo 中传递数据,而不是像下面一行那样在对象中传递数据,还要确保您的 addObserver 代码在发布通知之前运行。

NotificationCenter.default.post(name: NSNotification.Name(rawValue: "JSON"), object: nil, userInfo: ["json" : "your email/data"]) 

在你的 添加以下代码receiveJSNotification()

if let email = notification.userInfo?["json"] as? String {
        // do something with your image   
}

您在函数中收到的通知对象具有 userInfo 字典,该字典保存您在调用观察者时传递的数据。您可以从字典中获取数据并使用if let/guard let

-1赞 Darren Gates 5/14/2023 #3

这就是最终对我有用的东西:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

    NotificationCenter.default.addObserver(self, selector: #selector(receiveJsNotification(_:)),
                        name: NSNotification.Name ("JSON"), object: nil)


    // elsewhere in the app, we pass the value...
    let value = "some value";

    NotificationCenter.default.post(name: NSNotification.Name(rawValue: "JSON"), object: nil, userInfo: ["json" : value]) 

    return true
}


@objc
func receiveJsNotification(_ notification: Notification) {
    let jsonValue = notification.userInfo as AnyObject?
    
    if (jsonValue !== nil) {
        let someValue = jsonValue?.object(forKey: "json") ?? ""
        // do something with someValue here
    }
}