DistributedNotificationCenter - 如何在应用程序之间传递数据?
DistributedNotificationCenter - How to pass data between applications?
我构建了两个应用程序,"Main" 应用程序和一个支持它的 Finder Extension。使用 DistributedNotificationCenter 我可以成功地在应用程序之间来回 post 消息,并且已注册的观察者事件按预期触发。
问题似乎是我无法通过事件传递任何用户数据。所有文档都建议您可以传递 NSDictionary 或 [AnyHashable: Any] 对象作为 postNotificationName 的一部分
例如:发布消息看起来像这样...
let center: DistributedNotificationCenter = DistributedNotificationCenter.default()
center.postNotificationName(NSNotification.Name(name), object: nil, userInfo: mydata, deliverImmediately: true)
这是我的 Finder Extension 发送代码:
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 它是零,如果我查询 notification.object 它也是零。
想尽了办法,还是一头雾水
对于任何偶然发现此问题的人,事实证明我可以让它工作的唯一方法是 post 我自己的任何数据作为消息的一部分是将其包含在对象中 属性 在 postNotificationName 方法上。跨进程边界完全忽略 UserInfo。
所以我将我自己的类 CacheEntry 序列化为一个字符串,post 它,然后在另一边打开它。
所以像这样:
func sendMessage(名称: 字符串, 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) -> 字符串 {
let encoder = JSONEncoder()
let data = try! encoder.encode(messsagePayload)
let messsagePayloadString = String(data: data, encoding: .utf8)!
return String(messsagePayloadString)
}
func reconstructEntry(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)
}
}
沙盒应用似乎不允许使用 userInfo 参数
Important
Sandboxed apps can send notifications only if they do not contain a dictionary. If the sending application is in an App Sandbox, userInfo must be nil.
我构建了两个应用程序,"Main" 应用程序和一个支持它的 Finder Extension。使用 DistributedNotificationCenter 我可以成功地在应用程序之间来回 post 消息,并且已注册的观察者事件按预期触发。
问题似乎是我无法通过事件传递任何用户数据。所有文档都建议您可以传递 NSDictionary 或 [AnyHashable: Any] 对象作为 postNotificationName 的一部分
例如:发布消息看起来像这样...
let center: DistributedNotificationCenter = DistributedNotificationCenter.default()
center.postNotificationName(NSNotification.Name(name), object: nil, userInfo: mydata, deliverImmediately: true)
这是我的 Finder Extension 发送代码:
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 它是零,如果我查询 notification.object 它也是零。
想尽了办法,还是一头雾水
对于任何偶然发现此问题的人,事实证明我可以让它工作的唯一方法是 post 我自己的任何数据作为消息的一部分是将其包含在对象中 属性 在 postNotificationName 方法上。跨进程边界完全忽略 UserInfo。
所以我将我自己的类 CacheEntry 序列化为一个字符串,post 它,然后在另一边打开它。
所以像这样:
func sendMessage(名称: 字符串, 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) -> 字符串 {
let encoder = JSONEncoder()
let data = try! encoder.encode(messsagePayload)
let messsagePayloadString = String(data: data, encoding: .utf8)!
return String(messsagePayloadString)
}
func reconstructEntry(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)
}
}
沙盒应用似乎不允许使用 userInfo 参数
Important
Sandboxed apps can send notifications only if they do not contain a dictionary. If the sending application is in an App Sandbox, userInfo must be nil.