跨进程通信 macOS XPC 创建实例

一:简介

XPCmacOS 里苹果官方比较推荐和安全的的进程间通信机制。

集成流程简单,但是比较绕。

  • 主要需要集成 XPC Server 这个模块,这个模块最终会被 apple 的根进程 launchd 管理和以独立进程的方法唤起和关闭, 我们主app 进程并不需要管理这个进程的生命周期。

  • 特点:主要做权限分离和错误隔离使用,使用独立进程的方法,可以避免独立进程crash影响到主进程, 而且独立进程可以和主进程赋予不同的权限,比如是否沙盒,是否有网络权限等。

  • find /System/Library/Frameworks -name \*.xpc 命令可以查看系统使用的xpc服务。

  • 下面一张官方图,说明了对应的关系。
    UI App 作为 client 端,只要去监听对应的XPC 服务, launchd 就会拉起对应的 XPC Server
    XPC Server 作为 服务端,提供xpc服务,并接受client的消息。

    两者之间通过protocol 的方式进行互相调用,解耦。

  • 下面创建的app的数据流向

二:创建流程

  1. 创建主进程UI app
  2. 配置ui app的名字为 XpcApp.
  3. 按照步骤给 app 以添加target 的方式添加xpc 模块。
  4. 创建Xpc server 的名字为: XpcServer,
    api 选择OC 接口的api,而不是C接口的版本
    最后一项内嵌到UI APP中,最终运行打包后,会在XpcApp.app/Contents/XPCServices/XpcServer.xpc路径里面找到它。
  5. 最终的项目架构如下,
    XpcApp 包含两个文件夹,分别为 UI和xpcserver的文件夹,
    对应两个target。

三:demo 运行

  1. 由于XpcServer里面官方已经给了demo 足够运行的代码,我们可以不用添加任何代码就可以运行。
    我们在XpcServer.m 里面添加个 log 作为调试输出就行。
    这里只加了一句log输出,会在server 收到 ui app 传递来的消息的时候打印,并将收到的两个数字相加后返回。
objectivec 复制代码
// This implements the example protocol. Replace the body of this class with the implementation of this service's protocol.
- (void)performCalculationWithNumber:(NSNumber *)firstNumber andNumber:(NSNumber *)secondNumber withReply:(void (^)(NSNumber *))reply {
    NSInteger result = firstNumber.integerValue + secondNumber.integerValue;
    NSLog(@"server 收到 UI Clicent App的两个数字: %@, %@", firstNumber, secondNumber);
    reply(@(result));
}
  1. 配置UI App 文件。
    这里的代码调用方法可以参考XCode自动生成的XpcServerProtocol.h文件里面的注释,里面说明了怎么在Client 端发送消息。
    ViewController.m 中,替换成如下代码:
objectivec 复制代码
#import "ViewController.h"
#import "XpcServerProtocol.h"
#import "XpcServer.h"

@interface ViewController ()
@property (nonatomic, strong) NSXPCConnection *xpcConnect;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.xpcConnect =  [[NSXPCConnection alloc] initWithServiceName:@"com.jimbo.xpc.XpcServer"];
    NSXPCInterface *interface = [NSXPCInterface interfaceWithProtocol:@protocol(XpcServerProtocol)];
    self.xpcConnect.remoteObjectInterface = interface;
    [self.xpcConnect resume];
}


- (IBAction)sendMsgClick:(id)sender {
    NSLog(@"ui app 发送数字 231, 119");
    [[self.xpcConnect remoteObjectProxy] performCalculationWithNumber:@231 andNumber:@119 withReply:^(NSNumber *reply) {
        // We have received a response.
        NSLog(@"ui 收到了 xpc server 返回的数字: %@", reply);
    }];
}

- (void)dealloc {
    [self.xpcConnect  invalidate];
}

@end
  1. 在storyboard 中添加个button,绑定到上面的 - (IBAction)sendMsgClick:(id)sender方法中。
  2. 运行
    点击button 后,关注 app的控制台

    xpc server 的控制台

    两个进程都有打印消息,说明通讯成功。

四:备注

  1. demo中传递消息用的protocol里面的方法(performCalculationWithNumber: andNumber: withReply:)只是官方默认提供的,根据实际需要也可以添加其他方法,比如传递字符串,json等。
  2. 自己的xpc server 是内嵌到 app 包里的,默认只能有自己的app包的主程序进行调用,如果需要让其他app 进行通信调用,需要创建 launchd.plist 然后拷贝到系统路径下的.../LaunchDaemons文件夹。
    具体可以参考 man launchd.plist
  3. 两个进程都可以互相主动发消息的,只是demo没有添加对应的代码。
相关推荐
我是Superman丶8 小时前
Arduino IDE 安装教程:Windows/macOS/Linux 开发环境搭建
ide·windows·macos
k4m7v2pz8 小时前
Mac 上用 brew 安装 UTM 与 QEMU(代理配置全记录)
macos
千码君201612 小时前
提词器项目V1.0功能分析
ide·macos·xcode
承渊政道15 小时前
星空组网真实体验:Mac远程访问Ubuntu,SSH与HTTP全流程验证
ubuntu·http·macos·ssh·服务器管理·星空组网
深念Y15 小时前
黑苹果P400-直通显示折腾全记录-20260907
macos·ios·系统·黑苹果·苹果·英伟达·p400
DevLoom_18 小时前
MacBook 256GB到底够不够用,日常怎么清理空间?
macos·mac空间清理·mac磁盘空间不足
编程的一拳超人1 天前
DeepSeek Harness Linux/macOS/Windows 本地下载、启动与模型配置指南
linux·windows·macos·deepseek
时凌云.1 天前
【2026最新】JDK 下载安装与环境配置全教程(Windows/Mac/Linux 三平台,零基础友好)
java·linux·macos
HackTwoHub1 天前
BurpSuite2026.8专业(稳定版)下载Windows/Linux/Mac支持Java21以上(新增Burp AT智能体)
linux·运维·服务器·安全·macos·网络安全·自动化
海鸥两三1 天前
Mac电脑使用 Tabby 部署前端项目到阿里云服务器完整教程
前端·macos·阿里云