ios - 如何允许我的 Xcode 源代码编辑器扩展使用 XPC?

标签 ios xcode xpc xcode-extension

在这篇有关 Xcode 源代码编辑器扩展的文章中,提到 XPC 是规避应用程序沙箱的一种方法:

The extension must be sandboxed just to be loaded by Xcode, whereas calls to SourceKit needs to be un-sandboxed, which of course won’t fly in the App Store. We could distribute independently and use an un-sandboxed XPC service embedded in the extension.

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

如何将 Xcode 源代码编辑器扩展绑定(bind)到 XPC 服务?

最佳答案

多亏了LinuxSupportForXcode extension,我才能够解决这个问题。 .

我将假设您遵循 tutorial on creating an Xcode Extension Editor ,并将主项目制作为 macOS 应用程序。您应该有一个类似于以下内容的目标结构:

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

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

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

    出于示例目的,我们假设它名为 MyAppXPCService 并且其包标识符为 com.example.MyAppXPCService

  2. 将 XPC 服务依赖项从应用程序移至扩展程序:

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

    1. 转到您的应用的目标。
    2. 从框架和库中删除 MyAppXPCService.xpc。
    3. 转到您的扩展程序的目标。
    4. 将 MyAppXPCService.xpc 从项目导航器的产品文件夹中拖入,将其添加到框架和库中。将其保留为默认的“嵌入而不签名”。
  3. 在 XPC 服务中,将其转换为 Swift,mainly following the instructions here :

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

    1. 创建main.swiftMyService.swiftMyServiceDelegate.swiftMyServiceProtocol.swift通常情况下。

    2. 设置以下build设置:

      • 安装 Objective-C 兼容性 header :NO
      • Objective-C 生成的接口(interface) header 名称:``(空白)
    3. 在“build设置”中选择所需的 Swift 语言版本

    4. 在“build设置”中,添加(不要替换):@loader_path/../../../../Frameworks 到 < strong>运行时搜索路径。

      如果您不小心更换,并使用 embedded framework , XPC will crash on launch .

  4. 在您的扩展目标中:

    1. 导入 MyAppXPCService 以便它可以看到协议(protocol)。

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

      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 应用程序。

关于ios - 如何允许我的 Xcode 源代码编辑器扩展使用 XPC?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67491521/

相关文章:

ios - 如何从搜索结果 DetailView 返回 UITableView

ios - 我正在使用缓存图像,但是当我在 uitableview 中向上滚动时它一直在重新加载?

objective-c - 如何在 OSX 中调试 XPC 服务和客户端应用程序之间的通信

ios - 当我的应用程序进入前台时, View 不会重新加载刷新数据

ios - iOS 中不同方向的布局

ios - 将 UIImage 分成两半?

iphone - instrument工具中 "ObjectAlloc"和 "MallocDebug"如何添加使用

macos - 应用程序扩展中的安全范围书签

objective-c - 在 finder 同步扩展和 XPC 之间通信

ios - 调整 UITableViewCell 高度会导致更新结束时崩溃