【问题标题】:Cocoa/App Group Interprocess Communication via CFMessagePort通过 CFMessagePort 的 Cocoa/App Group 进程间通信
【发布时间】:2021-02-12 20:34:19
【问题描述】:

我正在尝试从一个 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 app中,我实现了:

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);



编辑: 似乎 remotePortnull,并导致崩溃 出现以下错误:

线程 1:EXC_BAD_ACCESS(代码=1,地址=0x8)

CoreFoundation`CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER: 0x7fff20707fe0 : testq %rdi, %rdi 0x7fff20707fe3 : 0x7fff20707fed ; 0x7fff20707fe5 : pushq %rbp 0x7fff20707fe6 : movq %rsp, %rbp 0x7fff20707fe9 : callq *0x10(%rdi) -> 0x7fff20707fec : popq %rbp 0x7fff20707fed : retq
0x7fff20707fee : nop
0x7fff20707fef : nop
0x7fff20707ff0 : nop
0x7fff20707ff1 : nop
0x7fff20707ff2 : nop
0x7fff20707ff3 : nop
0x7fff20707ff4 : nop
0x7fff20707ff5 : nop
0x7fff20707ff6 : nop




我不确定为什么 remotePort 会有 null 值。我在两个应用程序中使用相同的端口名称。

我一直在尝试使用 Stackoverflow 上的代码示例和其他帖子来解决这个问题,但我不明白我在哪里搞砸了。我将不胜感激任何建议!谢谢!

我看过的帖子:
https://nshipster.com/inter-process-communication/
CFMessagePort and sandboxing
Theos inter-app communication using mach ports
https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_security_application-groups

【问题讨论】:

    标签: objective-c cocoa ipc sandbox core-foundation


    【解决方案1】:

    阅读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");
    }
    

    【讨论】:

      猜你喜欢
      • 2012-06-19
      • 2017-09-10
      • 1970-01-01
      • 2015-07-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-04
      相关资源
      最近更新 更多