synchronization - Finder Sync Extension 和 Main App 应该如何通信?

标签 synchronization nsnotifications xpc findersync

我的用例:我有一个用于同步文件的“MainApp”。
我希望“MainApp”处理所有有关同步的服务器调用和其他 REST API 调用,例如文档共享等。

另一方面,我会有一个 Finder 同步扩展,它会显示同步状态图标覆盖。
它还将有一个文件上下文菜单项“共享”,它将显示一个共享对话框,用户可以在其中选择与谁共享文件。

问题:

  • FinderSyncExtension 和 MainApp 应该如何通信?是否应该使用 XCP,如果是,是否可以使用两种方式进行通信?例如 MainApp 通知 Finder 它应该刷新,因为一些文件已经同步,Finder 通知 MainApp 它应该执行“共享”操作。
  • 谁应该展示“分享”对话框?单击 FinderSyncExtension 的“共享”菜单项时,应显示共享表单。这应该由 finder 扩展程序或 MainApp 显示(假设 FinderExtension 通知它单击了“共享”项)。

  • 如果 Finder 扩展应该呈现表单,那么 FinderExtension 还应该从服务器检索数据(例如用于共享的联系人和组),我不确定 Finder 扩展是否应该对服务器执行任何网络调用。

    研究这个话题,我发现了几种方法:
  • FinderSyncExtension 和 MainApp 不直接通信。相反,FinderExtension 从数据库中读取数据以正确显示徽章。在这种情况下,尚不清楚 FinderExtension 在同步完成时应该如何更新,或者它应该如何通知 MainApp 执行某些操作。
  • XPC 通讯。我猜 FinderExtension 可以发起对 MainApp 的调用,但预期的方向相反吗?
  • macOS 进程之间是否存在某种 NotificationCenter?我试过 NSWorkspace.sharedWorkspace.notificationCenterNSDistributedNotificationCenter.defaultCenter但他们似乎没有在 MainApp 中传递通知。
  • 像 Seafile 项目中的 mach_ports?
  • 最佳答案

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

    主应用

    在主应用程序的某处,这种代码将监听消息端口:

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

    然后,在扩展中的某处(即当用户点击菜单项时):
    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");
    }
    

    这将向主应用程序发送一条消息。

    关于synchronization - Finder Sync Extension 和 Main App 应该如何通信?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41016558/

    相关文章:

    c# - .NET 的离线同步选项

    objective-c - NSNotifications 与同一协议(protocol)的多个实例的委托(delegate)

    ios - 出现时键盘高度会发生变化

    iphone - 如何在 UIView 中删除 NSNotification 的观察者?

    cocoa - 应用沙箱: how to allow XPC service to read file that user opened in parent app?

    c# - 在 C# 中使用 DirSync 不仅返回更改的值

    c - 使用信号量的 sleep 理发师

    php - 使我的代码异步,这样就不会永远加载

    cocoa - XPC 服务返回 NSAttributtedString

    objective-c - 应该如何编写带有状态的 XPC 服务?