【问题标题】:DistributedNotificationCenter - How to pass data between applications?DistributedNotificationCenter - 如何在应用程序之间传递数据?
【发布时间】:2020-05-22 21:12:19
【问题描述】:

我已经构建了两个应用程序“主”应用程序和一个支持它的 Finder 扩展程序。使用 DistributedNotificationCenter 我可以成功地在应用程序之间来回发布消息,并且注册的观察者事件按预期触发。

问题似乎是我无法通过事件传递任何用户数据。所有文档都建议您可以将 NSDictionary[AnyHashable: Any] 对象作为 postNotificationName

的一部分传递

例如:发布消息看起来像这样......

let center: DistributedNotificationCenter = DistributedNotificationCenter.default()
center.postNotificationName(NSNotification.Name(name), object: nil, userInfo: mydata, deliverImmediately: true)

这是我的 Finder 扩展发送代码:

    var myInfo = [AnyHashable: Any]()
    myInfo[AnyHashable("filename")] = "Test Data"

    let center: DistributedNotificationCenter = DistributedNotificationCenter.default()
    center.postNotificationName(NSNotification.Name("RequestSyncState"), object: nil, userInfo: myInfo, deliverImmediately: true)

主应用接收代码:

    @objc func recievedMessage(notification:NSNotification){
    NSLog ("Message Recieved from Finder Extension \(notification.name.rawValue)")

    if notification.name.rawValue == "RequestSyncState" {
        NSLog ("Message Recieved from Finder to determine the sync icon")
        guard let userInfo = notification.userInfo else
        {
            return
        }

        guard let value = userInfo["Filename"]  else
        {
            NSLog ("Message payload is empty")
            return
        }

        NSLog ("Message payload is \(value)")
    }

正如我所说,这些函数触发并收到通知,只是没有实际数据。如果我查询 notification.userInfo 它是 nil,如果我查询 notification.object 它也是 nil。

我尝试了我能想到的一切,但我完全不知所措。

【问题讨论】:

    标签: swift macos nsnotificationcenter macos-catalina


    【解决方案1】:

    对于任何偶然发现此问题的人,事实证明,我可以使其工作的唯一方法是将我自己的任何数据作为消息的一部分发布,是将其包含在 postNotificationName 方法的 Object 属性中。跨进程边界完全忽略 UserInfo。

    所以我将自己的类 CacheEntry 序列化为一个字符串,发布它,然后在另一边解包。

    比如:

    func sendMessage(name: String, data:CacheEntry) {

        let message:String = createMessageData(messsagePayload: data)
        
        let center: DistributedNotificationCenter = DistributedNotificationCenter.default()
        center.postNotificationName(NSNotification.Name(name), object: message, userInfo: nil, deliverImmediately: true)
    }
    

    func createMessageData(messsagePayload:CacheEntry) -> String {

        let encoder = JSONEncoder()
        let data = try! encoder.encode(messsagePayload)
        
        let messsagePayloadString = String(data: data, encoding: .utf8)!
    
        return String(messsagePayloadString)
    }
    

    func rebuildEntry(messagePayload:String) -> CacheEntry {

        let jsonData = messagePayload.data(using: .utf8)!
        let messsagePayloadCacheEntry = try! JSONDecoder().decode(CacheEntry.self, from: jsonData)
        
        return messsagePayloadCacheEntry
    
    }
    
    @objc func recievedMessage(notification:NSNotification){
       
        NSLog ("Message Received from Application \(notification.name)")
        
        if notification.name.rawValue == "DSF-SetSyncState" {
            
            NSLog ("Message Recieved from Application to set the sync icon")
            
            let cEntry = reconstructEntry(messagePayload: notification.object as! String)
    
        }
        
    
        }
    

    【讨论】:

      【解决方案2】:

      看起来沙盒应用不允许使用 userInfo 参数

      重要

      只有在不包含字典的情况下,沙盒应用才能发送通知。如果发送应用在 App Sandbox 中,则 userInfo 必须为 nil。

      https://developer.apple.com/documentation/foundation/nsdistributednotificationcenter/1418360-postnotificationname

      【讨论】:

      • 这不是解决方案,因此最好在 cmets 中发布。
      • 我没有足够的声誉来做这件事,因为这是我的第一篇文章。奇怪的是,它可以让您在更隐藏的帖子之前发布更多可见的帖子。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多