1

在这篇关于 Xcode Source Editor 扩展的文章中,它提到了 XPC 是一种绕过应用程序沙箱的方法:

扩展必须经过沙盒处理才能由 Xcode 加载,而对 SourceKit 的调用需要取消沙盒处理,这当然不会在 App Store 中运行。我们可以独立分发并使用嵌入在扩展中的非沙盒XPC 服务。

但是,我不确定如何将所有内容联系在一起以使用 XPC 服务。

如何将我的 Xcode Source Editor 扩展绑定到 XPC 服务?

4

1 回答 1

1

感谢LinuxSupportForXcode 扩展,我能够解决这个问题。

我将假设您遵循有关创建 Xcode 扩展编辑器的教程,并将主项目设为 macOS 应用程序。您应该具有类似于以下内容的目标结构:

  • MyApp(macOS 应用程序目标)
  • MyAppExtension(Xcode 源代码编辑器扩展目标)

要将 XPC 与源代码编辑器扩展一起使用:

  1. 文件 > 新建 > 目标... > XPC 服务。

    例如,我们假设它被调用MyAppXPCService并且它的包标识符是com.example.MyAppXPCService.

  2. 将 XPC 服务依赖从 App 移至 Extension:

    如果您不执行此步骤,您可能会遇到扩展未执行 XPCService 的问题。例如,您调用了一个应该启动 XPCService 的命令,但是在 Xcode Debug Navigator 中,您的 XPCService 永远不会出现。

    1. 转到您的应用程序的目标。
    2. 从框架和库中删除 MyAppXPCService.xpc。
    3. 转到您的扩展程序的目标。
    4. 通过将 MyAppXPCService.xpc 从 Project Navigator 的 products 文件夹中拖入,将其添加到 Frameworks and Libraries。将其保留为默认的“不签名嵌入”。
  3. 在 XPC 服务中,将其转换为 Swift,主要按照这里的说明进行操作

    注意:如果您不想转换为 Swift,而是使用混合目标,只需创建一个 Swift 文件,并在出现提示时选择创建桥接头,然后包含#import "MyAppXPCServiceProtocol.h"在桥接头中。

    1. 创建main.swift, MyService.swift, MyServiceDelegate.swift,MyServiceProtocol.swift正常。

    2. 设置以下构建设置:

      • 安装 Objective-C 兼容性头文件NO
      • Objective-C 生成的接口标题名称:``(空白)
    3. 在构建设置中选择您想要的Swift 语言版本。

    4. 在 Build Settings 中,添加(不要替换):@loader_path/../../../../FrameworksRuntime Search Paths

      如果您不小心更换并使用了嵌入式框架XPC 将在启动时崩溃

  4. 在您的扩展目标中:

    1. import MyAppXPCService以便它可以看到协议。

    2. 使用 XPC 目标的捆绑标识符serviceName创建连接:

      private let connection = { () -> NSXPCConnection in
        let connection = NSXPCConnection(serviceName: <#"com.example.MyAppXPCService"#>)
        connection.remoteObjectInterface = NSXPCInterface(with: MyAppXPCServiceProtocol.self)
        return connection
      }()
      
    3. 调用您的 XPC 服务:

      private func xpcUpperCase(input: String) {
        connection.resume()
        defer { connection.suspend() }
        guard let xpcService = connection.remoteObjectProxy as? MyAppXPCServiceProtocol else {
          throw NSError()
        }
      
        xpcService.upperCaseString(input) { output in
          print(output)
        }
      }
      

创建连接的好处是它会自动启动您的 XPC 服务,而无需运行 UI 应用程序。

于 2021-05-11T17:18:51.133 回答