XPC 到 XPC 通信

Posted

技术标签:

【中文标题】XPC 到 XPC 通信【英文标题】:XPC to XPC Communication 【发布时间】:2017-01-10 10:45:23 【问题描述】:

我正在开发一个应用程序,我从主应用程序中分离出两个不同的 XPC 服务。我希望 XPC 服务与其他 XPC 服务进行通信,该服务将进行一些处理并将数据返回给第一个服务,第一个服务将进行自己的处理,然后将数据返回给主应用程序。我什至尝试过这个,但是服务之间的通信会给出“无法与帮助应用程序通信”的错误。

我的问题是这是否可能?如果是,那需要什么?

任何帮助将不胜感激。

【问题讨论】:

【参考方案1】:

是的,这是可能的,但一点也不明显。我断断续续地问了一年关于这个确切问题的问题,直到一位 Apple 工程师的隐晦暗示让我偶然发现了答案。

诀窍是您需要将一个进程的NSXPCListenerEndpoint 转移到另一个进程。然后,第二个进程可以使用该端点对象创建与第一个进程的直接连接。问题是,虽然 NSXPCListenerEndpointNSCoding 兼容,但它只能通过现有的 XPC 连接进行编码,这使得这个问题听起来像一个 catch-22(在创建一个连接,并且在拥有端点之前无法创建连接)。

解决方案(“技巧”)是您需要一个中间进程(我们称之为“基石”),它已经具有可以在其他两个进程之间交换端点的 XPC 连接。

在我的应用程序中,我最终创建了一个守护进程作为我的基石,但我认为您可以直接在您的应用程序中执行此操作。以下是您需要做的:

    使用两个 XPC 服务“A”和“B”创建应用程序 在“A”中获取进程的侦听器对象:获取自动创建的服务侦听器 (listener = NSXPCListener.serviceListener) 或为第二个进程创建专用的匿名侦听器(使用 listener = NSXPCListener.anonymousListener)。 获取监听器的端点 (listener.endpoint) 应用程序应向“A”询问其端点。 然后应用程序可以启动“B”,并再次使用 XPC,将它从“A”获得的端点传递给“B”。 “B”现在可以使用它从“A”获得的端点对象(通过应用程序)通过[[NSXPCConnection alloc] initWithListenerEndpoint:aEndpoint]] 创建到“A”的直接连接。

【讨论】:

【参考方案2】:

所以我发现两个进程不可避免地无法与同一个 XPCService 通信。那是因为如果您尝试启动 XPCService,它将是启动器的唯一进程。据我所知,您只能与您的进程启动的 XPCService 进行通信。

所以我相信您的第二个 XPCService 将无法“启动”第一个 XPCService,因此将无法与之通信。

您可能做的最好的事情是让您的第二个 XPCService 与您的主应用程序进程通信,然后它与第一个 XPCService 通信。

你可以这样做:

   [[self.firstXPCConnection remoteObjectProxy] getSomeString:^(NSString *myString) 
        [[self.secondXPCConnection remoteObjectProxy] passSomeString:myString];
   ];

虽然免责声明,但我还没有尝试过。但我能用我所拥有的知识为您提供最好的帮助

【讨论】:

您可以使用-NSXPCConnection initWithMachServiceName:options: 创建一个新的 NSXPCConnection,只要另一个 XPC 有一个可以接受连接的委托。

以上是关于XPC 到 XPC 通信的主要内容,如果未能解决你的问题,请参考以下文章

使用 XPC 与另一个应用程序通信

XPC 蓝牙通信崩溃

通过 XPC 与应用程序通信并启动以 root 身份运行的守护程序

iOS 集成测试随机崩溃:与 backboardd 通信时遇到 XPC 错误

服务和客户端应用程序之间的 XPC 通信仅在从 xcode 启动时才有效

非常简单的 macOS XPC