Mac OS X XPC作为两个应用程序之间的进程间通信(IPC)方式

11
我有一个带窗口的应用程序和一个无窗口的辅助程序,它们都在应用程序包中,并作为登录项工作。应用程序可以启动和停止助手,一切都正常。问题是我需要在它们之间创建双向通信通道,并且它应该在沙盒和非沙盒版本中工作,最好在OS X 10.7+中也能工作。
我调查了这个话题并发现XPC可以提供点对点连接。我阅读了苹果的相关文档以及以下几个主题:

是否可能使用Mac OS X XPC像IPC一样在进程之间交换消息?如何操作?
使用XPC与另一个应用程序通信
http://afewguyscoding.com/2012/07/ipc-easy-introducing-xpc-nsxpcconnection/
https://www.objc.io/issues/14-mac/xpc/

但我找不到任何关于如何组织我的XCode项目的描述。我有两个目标:“主应用程序”和“助手应用程序”。现在我需要添加第三个模板,作为XPC服务。好了,但接下来该怎么办?这个XPC bundle应该放在哪里才能对两个应用程序都可用?请注意,助手位于主应用程序包中,因为它是登录项。因此,我需要一些明确的说明或者一个XCode项目示例。

谢谢, Alex


我现在正在处理这个问题 - 你有进展吗?我的当前策略是创建两个XPCServices,一个用于每个应用程序。然后找到一种服务之间通信的方法?这很困难,但我相信目前不可能直接从一个应用程序直接通信到另一个应用程序。我认为必须有一个XPCService介于其中。 - A O
1个回答

11

对于一直在努力解决这个问题的人,我终于成功地使用 NSXPCConnection 在两个应用程序之间实现了100%的通信。

需要注意的关键点是,你只能创建一个NSXPCConnection 来连接三件事情:

  1. XPC服务。您可以通过名称严格连接到XPC服务。
  2. Mach服务。 您也可以通过名称严格连接到Mach服务。
  3. NSXPCEndpoint。 这是我们正在寻找的,用于在两个应用程序之间进行通信。

问题在于我们无法直接从一个应用程序传输一个NSXPCEndpoint到另一个应用程序。

必须创建一个包含NSXPCEndpoint属性的 machservice Launch Agent(请参见此示例)。一个应用程序可以连接到machservice,并将该属性设置为自己的[NSXPCListener anonymousListener].endpoint

然后,另一个应用程序可以连接到machservice,并请求该端点。

然后,使用该端点可以创建一个NSXPCConnection,成功地在两个应用程序之间建立了桥梁。我已经测试了来回发送对象,它都按预期工作。

请注意,如果您的应用程序受到沙箱限制,则必须创建一个XPCService,作为应用程序和Machservice之间的中间人。

我很高兴我解决了这个问题-- 我在SO上相当活跃,所以如果有人对源代码感兴趣,只需添加评论,我可以投入更多时间来发布更多细节。

我遇到的一些问题:

必须启动machservice,以下是相关代码:

   OSStatus                    err;
   AuthorizationExternalForm   extForm;

   err = AuthorizationCreate(NULL, NULL, 0, &self->_authRef);
   if (err == errAuthorizationSuccess) {
      NSLog(@"SUCCESS AUTHORIZING DAEMON");
   }
   assert(err == errAuthorizationSuccess);

   Boolean             success;
   CFErrorRef          error;

   success = SMJobBless(
                        kSMDomainSystemLaunchd,
                        CFSTR("DAEMON IDENTIFIER HERE"),
                        self->_authRef,
                        &error
                        );

同时,每次重新生成您的守护程序时,您都需要使用以下bash命令卸载先前的启动代理:

sudo launchctl unload /Library/LaunchDaemons/com.example.apple-samplecode.EBAS.HelperTool.plist
sudo rm /Library/LaunchDaemons/com.example.apple-samplecode.EBAS.HelperTool.plist
sudo rm /Library/PrivilegedHelperTools/com.example.apple-samplecode.EBAS.HelperTool

(当然要使用您对应的标识符)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接