我的用例:我有一个“MainApp”来同步文件。
我希望“MainApp”处理所有有关同步的服务器调用以及其他REST API调用,例如文档共享等。
另一方面,我将拥有一个Finder Sync Extension,它将显示同步状态图标叠加层。
它还有一个文件上下文菜单项“共享”,它将显示一个共享对话框,用户可以在其中选择与谁共享文件。
问题:
如果Finder Extension应该显示该表单,则FinderExtension也应该从服务器检索数据(例如用于共享的联系人和组),并且我不确定Finder Extension是否应该对服务器执行任何网络调用。
研究该主题后,我发现了几种方法:
NSWorkspace.sharedWorkspace.notificationCenter
和NSDistributedNotificationCenter.defaultCenter
,但它们似乎未在MainApp中传递通知。 最佳答案
我设法通过CFMessagePort
API做到了这一点。为了使沙盒扩展程序和主应用程序进行通信,需要在Xcode功能中启用AppGroup。此外,带后缀的应用程序组 key (由您选择)需要用作消息端口标识符。
主要应用程式
在主应用程序中的某处,这种代码将在消息端口上监听:
CFMessagePortRef port = CFMessagePortCreateLocal(nil, CFSTR("group.com.yourapp.mach_or_something"), Callback, nil,
nil);
CFRunLoopSourceRef runLoopSource = CFMessagePortCreateRunLoopSource(nil, port, 0);
CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopCommonModes);
Callback
是一种实现为:static CFDataRef Callback(CFMessagePortRef port, SInt32 messageID, CFDataRef data, void* info)
{
NSData* objcData = (__bridge NSData*) data;
NSLog(@"Message received: %@", [NSString.alloc initWithData:objcData encoding:NSASCIIStringEncoding]);
return data;
}
Finder同步扩展
然后,在扩展程序中的某个位置(即,当用户点击菜单项时):
CFDataRef data = CFDataCreate(NULL, (const UInt8*) "somedata", 8);
SInt32 messageID = 0x1111; // Arbitrary
CFTimeInterval timeout = 1;
CFMessagePortRef remotePort = CFMessagePortCreateRemote(nil, CFSTR("group.com.yourapp.mach_or_something"));
SInt32 status = CFMessagePortSendRequest(remotePort, messageID, data, timeout, timeout, NULL, NULL);
if (status == kCFMessagePortSuccess)
{
NSLog(@"SUCCESS STATUS");
}
else
{
NSLog(@"FAIL STATUS");
}
这将向主应用程序发送一条消息。