How should Finder Sync Extension and Main App communicate?

泪湿孤枕 提交于 2019-11-28 08:49:14

I managed to do this via CFMessagePort API. In order to have sandboxed extension and main app to communicate, AppGroups need to be enabled in Xcode capabilities. Additionally, app-group key with suffix (by your choice) needs to be used as message-port identifier.

Main app

Somewhere in the main app, this kind of code would listen on message port:

CFMessagePortRef port = CFMessagePortCreateLocal(nil, CFSTR("group.com.yourapp.mach_or_something"), Callback, nil,
                                                 nil);
CFRunLoopSourceRef runLoopSource = CFMessagePortCreateRunLoopSource(nil, port, 0);
CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopCommonModes);

Callback is a method implemented as:

static CFDataRef Callback(CFMessagePortRef port, SInt32 messageID, CFDataRef data, void* info)
{
    NSData* objcData = (__bridge NSData*) data;
    NSLog(@"Message received: %@", [NSString.alloc initWithData:objcData encoding:NSASCIIStringEncoding]);
    return data;
}

Finder Sync Extension

And then, somewhere in the extension (ie when user taps on menu item):

CFDataRef data = CFDataCreate(NULL, (const UInt8*) "somedata", 8);
SInt32 messageID = 0x1111; // Arbitrary
CFTimeInterval timeout = 1;

CFMessagePortRef remotePort = CFMessagePortCreateRemote(nil, CFSTR("group.com.yourapp.mach_or_something"));

SInt32 status = CFMessagePortSendRequest(remotePort, messageID, data, timeout, timeout, NULL, NULL);
if (status == kCFMessagePortSuccess)
{
    NSLog(@"SUCCESS STATUS");
}
else
{
    NSLog(@"FAIL STATUS");
}

This will send a message to the main application.

Apple documentation about sandboxed Mach Inter-Process Communication:

https://developer.apple.com/library/archive/documentation/Security/Conceptual/AppSandboxDesignGuide/AppSandboxInDepth/AppSandboxInDepth.html#//apple_ref/doc/uid/TP40011183-CH3-SW24

IPC and POSIX Semaphores and Shared Memory

Normally, sandboxed apps cannot use Mach IPC, POSIX semaphores and shared memory, or UNIX domain sockets (usefully). However, by specifying an entitlement that requests membership in an application group, an app can use these technologies to communicate with other members of that application group.

Any semaphore or Mach port that you wish to access within a sandboxed app must be named according to a special convention:

  • POSIX semaphores and shared memory names must begin with the application group identifier, followed by a slash (/), followed by a name of your choosing. Mach port names must begin with the application group identifier, followed by a period (.), followed by a name of your choosing.

  • For example, if your application group’s name is Z123456789.com.example.app-group, you might create two semaphores named Z123456789.myappgroup/rdyllwflg and Z123456789.myappgroup/bluwhtflg. You might create a Mach port named Z123456789.com.example.app-group.Port_of_Kobe.

Note: The maximum length of a POSIX semaphore name is only 31 bytes, so if you need to use POSIX semaphores, you should keep your app group names short.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!