本文介绍了Finder Sync Extension和Main App应该如何通信?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的用例:我有一个"MainApp"来同步文件.我希望'MainApp'处理所有有关同步的服务器调用以及其他REST API调用,例如文档共享等.

My use case: I have a 'MainApp' which does the syncing of files.I would like that 'MainApp' handles all server calls regarding syncing and other REST API calls such as document-sharing, etc.

另一方面,我将拥有一个Finder Sync Extension,它将显示同步状态图标叠加层.它还会有一个文件上下文菜单项共享",它将显示一个共享对话框,用户可以在其中选择与谁共享文件.

On the other hand, I would have a Finder Sync Extension which would show sync-status icon overlays.It would also have a file-context-menu-item 'Share' which would present a Share dialog where users can choose with whom to share the file.

问题:

  1. FinderSyncExtension和MainApp应该如何通信?应该使用XCP吗?如果可以,双向通信是否可以?例如,MainApp通知Finder应当刷新,因为某些文件已经同步,而Finder通知MainApp应当执行共享"操作.

  1. How should FinderSyncExtension and MainApp communicate? Should XCP be utilised and if so, is it ok that communication is two-ways? For example MainApp informing Finder it should refresh because some files have been synced, and Finder informing MainApp that it should perform 'Share' operation.

谁应该显示共享"对话框?单击FinderSyncExtension的共享"菜单项时,应显示一个共享表单.应该通过finder扩展程序还是MainApp进行显示(假设FinderExtension通知它单击了共享"项).

Who should present 'Share' dialog? When FinderSyncExtension 'Share' menu item is clicked, a Share form should be displayed. Should this be displayed by the finder extension or by the MainApp (assuming FinderExtension informed it that 'Share' item was clicked).

如果Finder扩展名应显示该表单,则FinderExtension也应从服务器中检索数据(例如用于共享的联系人和组),并且我不确定Finder扩展名是否应该对服务器执行任何网络调用.

If Finder extension should present the form, then FinderExtension should also retrieve data from the server (such as contacts and groups for sharing) and I'm not sure if Finder Extension should perform any network calls towards the server.

在研究该主题时,我发现了几种方法:

Researching the topic, I found several approaches:

  1. FinderSyncExtension和MainApp不直接通信.取而代之的是,FinderExtension从数据库读取数据以正确显示徽章.在这种情况下,不清楚同步完成后如何更新FinderExtension或如何通知MainApp执行某些操作.
  2. XPC通信.我猜FinderExtension可以启动对MainApp的调用,但是是否会出现相反的方向?
  3. macOS进程之间是否存在某种NotificationCenter?我尝试使用NSWorkspace.sharedWorkspace.notificationCenterNSDistributedNotificationCenter.defaultCenter进行操作,但它们似乎未在MainApp中传递通知.
  4. mach_ports是否与Seafile项目中的一样?
  1. FinderSyncExtension and MainApp don't communicate directly. Instead, FinderExtension reads data from database to properly show badges. In this scenario it is unclear how FinderExtension should update when sync is finished or how should it inform MainApp to perform some action.
  2. XPC communication. I guess FinderExtension could initiate calls to MainApp but is opposite direction expected?
  3. Is there some kind of NotificationCenter between macOS processes? I tried with NSWorkspace.sharedWorkspace.notificationCenter and with NSDistributedNotificationCenter.defaultCenter but they don't seem to deliver notification in MainApp.
  4. mach_ports as in Seafile project?

推荐答案

我设法通过CFMessagePort API做到了这一点.为了使沙盒扩展程序和主应用程序进行通信,需要在Xcode功能中启用AppGroup.此外,带有后缀(由您选择)的应用程序组密钥需要用作消息端口标识符.

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.

在主应用程序的某个地方,这种代码将在消息端口上侦听:

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是一种实现为:

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同步扩展程序

然后,在扩展名中的某个位置(即,当用户点击菜单项时):

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.

这篇关于Finder Sync Extension和Main App应该如何通信?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-19 01:33