Cocoa/App 通过 CFMessagePort 的组进程间通信
Cocoa/App Group Interprocess Communication via CFMessagePort
我正在尝试将一个字符串(虽然我的真正目标是传递一个数组)从一个 macOS 应用程序传递到另一个。接收方应用程序被沙盒化,而发送方应用程序未被沙盒化。
我已经为这两个应用程序添加了一个应用程序组 (DEV_TEAM_ID.com.if.APP_NAME.UNIQUE_NAME
)。
在接收器应用程序中,我已经实现了创建端口和运行循环:
CFMessagePortRef localPort =
CFMessagePortCreateLocal(nil,
CFSTR("DEV_TEAM_ID.com.if.APP_NAME.UNIQUE_NAME"),
PortCallBack,
nil,
nil);
CFRunLoopSourceRef runLoopSource =
CFMessagePortCreateRunLoopSource(nil, localPort, 0);
CFRunLoopAddSource(CFRunLoopGetCurrent(),
runLoopSource,
kCFRunLoopCommonModes);
当然还有回调:
CFDataRef PortCallBack(CFMessagePortRef local, SInt32 msgid, CFDataRef data, void *info) {
char *message = "Thanks for saying hello!";
CFDataRef returnData = CFDataCreate(NULL, (const UInt8 *)message, strlen(message)+1);
printf("here is our received data: %s\n", CFDataGetBytePtr(data));
return returnData;
}
在 sender 应用程序 中,我实现了:
CFMessagePortRef remotePort = CFMessagePortCreateRemote(nil, CFSTR("DEV_TEAM_ID.com.if.APP_NAME.UNIQUE_NAME"));
SInt32 messageIdentifier = 1;
CFDataRef messageData = (__bridge CFDataRef)[@"hello, friend." dataUsingEncoding:NSUTF8StringEncoding];
SInt32 status = CFMessagePortSendRequest(remotePort, messageIdentifier, messageData, 1000, 0, NULL, NULL);
if (status == kCFMessagePortSuccess)
{
NSLog(@"success");
}
receiver 应用程序启动正常,但 sender 应用程序在这一行崩溃:
SInt32 status = CFMessagePortSendRequest(remotePort, messageIdentifier, messageData, 1000, 0, NULL, NULL);
编辑: remotePort
似乎是 null,并且导致了崩溃
出现以下错误:
Thread 1: EXC_BAD_ACCESS (code=1, address=0x8)
CoreFoundation`CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER:
0x7fff20707fe0 <+0>: testq %rdi, %rdi
0x7fff20707fe3 <+3>: je 0x7fff20707fed ; <+13>
0x7fff20707fe5 <+5>: pushq %rbp
0x7fff20707fe6 <+6>: movq %rsp, %rbp
0x7fff20707fe9 <+9>: callq *0x10(%rdi)
-> 0x7fff20707fec <+12>: popq %rbp
0x7fff20707fed <+13>: retq
0x7fff20707fee <+14>: nop
0x7fff20707fef <+15>: nop
0x7fff20707ff0 <+16>: nop
0x7fff20707ff1 <+17>: nop
0x7fff20707ff2 <+18>: nop
0x7fff20707ff3 <+19>: nop
0x7fff20707ff4 <+20>: nop
0x7fff20707ff5 <+21>: nop
0x7fff20707ff6 <+22>: nop
我不确定为什么 remotePort
会有 null 值。我在两个应用程序中使用相同的端口名称。
我一直在尝试使用 Whosebug 上的代码示例和其他帖子来解决这个问题,但我不明白我在哪里搞砸了。我将不胜感激任何建议!谢谢!
我看过的帖子:
https://nshipster.com/inter-process-communication/
CFMessagePort and sandboxing
https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_security_application-groups
阅读后我能够解决这个问题 Using App Groups for communication between macOS/iOS apps from the Same Vendor
问题是,从 Big Sur(或可能是 Catalina)开始,使用 App Groups 的 macOS 应用程序需要在开发者门户中创建一个组容器。这样做之后,您需要重新配置代码签名您的应用程序以包含配置文件。我不太确定这一切何时成为一项要求,因为 Apple 并没有很好地记录设置应用程序组。按照上述链接文章中的步骤进行操作后,一切正常。
我能够将数组从一个应用程序传递到另一个应用程序:
NSData* myData = [NSKeyedArchiver archivedDataWithRootObject:self.runningProcs];
CFMessagePortRef remotePort = CFMessagePortCreateRemote(kCFAllocatorSystemDefault, CFSTR("group.DEV_TEAM_ID.com.if.APP_NAME.UNIQUE_NAME"));
SInt32 messageIdentifier = 1;
CFDataRef messageData = (__bridge CFDataRef)(myData);
SInt32 status = CFMessagePortSendRequest(remotePort, messageIdentifier, messageData, 1000, 0, NULL, NULL);
if (status == kCFMessagePortSuccess)
{
NSLog(@"success");
}
我正在尝试将一个字符串(虽然我的真正目标是传递一个数组)从一个 macOS 应用程序传递到另一个。接收方应用程序被沙盒化,而发送方应用程序未被沙盒化。
我已经为这两个应用程序添加了一个应用程序组 (DEV_TEAM_ID.com.if.APP_NAME.UNIQUE_NAME
)。
在接收器应用程序中,我已经实现了创建端口和运行循环:
CFMessagePortRef localPort =
CFMessagePortCreateLocal(nil,
CFSTR("DEV_TEAM_ID.com.if.APP_NAME.UNIQUE_NAME"),
PortCallBack,
nil,
nil);
CFRunLoopSourceRef runLoopSource =
CFMessagePortCreateRunLoopSource(nil, localPort, 0);
CFRunLoopAddSource(CFRunLoopGetCurrent(),
runLoopSource,
kCFRunLoopCommonModes);
当然还有回调:
CFDataRef PortCallBack(CFMessagePortRef local, SInt32 msgid, CFDataRef data, void *info) {
char *message = "Thanks for saying hello!";
CFDataRef returnData = CFDataCreate(NULL, (const UInt8 *)message, strlen(message)+1);
printf("here is our received data: %s\n", CFDataGetBytePtr(data));
return returnData;
}
在 sender 应用程序 中,我实现了:
CFMessagePortRef remotePort = CFMessagePortCreateRemote(nil, CFSTR("DEV_TEAM_ID.com.if.APP_NAME.UNIQUE_NAME"));
SInt32 messageIdentifier = 1;
CFDataRef messageData = (__bridge CFDataRef)[@"hello, friend." dataUsingEncoding:NSUTF8StringEncoding];
SInt32 status = CFMessagePortSendRequest(remotePort, messageIdentifier, messageData, 1000, 0, NULL, NULL);
if (status == kCFMessagePortSuccess)
{
NSLog(@"success");
}
receiver 应用程序启动正常,但 sender 应用程序在这一行崩溃:
SInt32 status = CFMessagePortSendRequest(remotePort, messageIdentifier, messageData, 1000, 0, NULL, NULL);
编辑: remotePort
似乎是 null,并且导致了崩溃
出现以下错误:
Thread 1: EXC_BAD_ACCESS (code=1, address=0x8)
CoreFoundation`CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER: 0x7fff20707fe0 <+0>: testq %rdi, %rdi 0x7fff20707fe3 <+3>: je 0x7fff20707fed ; <+13> 0x7fff20707fe5 <+5>: pushq %rbp 0x7fff20707fe6 <+6>: movq %rsp, %rbp 0x7fff20707fe9 <+9>: callq *0x10(%rdi) -> 0x7fff20707fec <+12>: popq %rbp 0x7fff20707fed <+13>: retq
0x7fff20707fee <+14>: nop
0x7fff20707fef <+15>: nop
0x7fff20707ff0 <+16>: nop
0x7fff20707ff1 <+17>: nop
0x7fff20707ff2 <+18>: nop
0x7fff20707ff3 <+19>: nop
0x7fff20707ff4 <+20>: nop
0x7fff20707ff5 <+21>: nop
0x7fff20707ff6 <+22>: nop
我不确定为什么 remotePort
会有 null 值。我在两个应用程序中使用相同的端口名称。
我一直在尝试使用 Whosebug 上的代码示例和其他帖子来解决这个问题,但我不明白我在哪里搞砸了。我将不胜感激任何建议!谢谢!
我看过的帖子:
https://nshipster.com/inter-process-communication/
CFMessagePort and sandboxing
https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_security_application-groups
阅读后我能够解决这个问题 Using App Groups for communication between macOS/iOS apps from the Same Vendor
问题是,从 Big Sur(或可能是 Catalina)开始,使用 App Groups 的 macOS 应用程序需要在开发者门户中创建一个组容器。这样做之后,您需要重新配置代码签名您的应用程序以包含配置文件。我不太确定这一切何时成为一项要求,因为 Apple 并没有很好地记录设置应用程序组。按照上述链接文章中的步骤进行操作后,一切正常。
我能够将数组从一个应用程序传递到另一个应用程序:
NSData* myData = [NSKeyedArchiver archivedDataWithRootObject:self.runningProcs];
CFMessagePortRef remotePort = CFMessagePortCreateRemote(kCFAllocatorSystemDefault, CFSTR("group.DEV_TEAM_ID.com.if.APP_NAME.UNIQUE_NAME"));
SInt32 messageIdentifier = 1;
CFDataRef messageData = (__bridge CFDataRef)(myData);
SInt32 status = CFMessagePortSendRequest(remotePort, messageIdentifier, messageData, 1000, 0, NULL, NULL);
if (status == kCFMessagePortSuccess)
{
NSLog(@"success");
}