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

问题描述

在这篇关于 Xcode 源代码编辑器扩展的文章中,它提到 xpc 是一种绕过应用沙箱的方法

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

但是,我不确定如何将所有内容组合在一起以使用 xpc 服务。

如何将我的 Xcode 源代码编辑器扩展绑定到 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 Debug Navigator 中,您的 XPCService 永远不会出现。

    1. 转到您应用的目标。
    2. 从框架和库中删除 MyAppXPCService.xpc。
    3. 转到扩展程序的目标。
    4. 将 MyAppXPCService.xpc 从 Project Navigator 的 products 文件夹中拖入,将其添加到 Frameworks 和 Libraries。将其保留为默认的“嵌入而不签名”。
  3. 在 XPC Service 中,将其转换为 Swift,mainly following the instructions here

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

    1. 正常创建 #import "MyAppXPCServiceProtocol.h"main.swiftMyService.swiftMyServiceDelegate.swift

    2. 设置以下构建设置:

      • 安装 Objective-C 兼容性标头MyServiceProtocol.swift
      • Objective-C 生成的接口头名称:``(空白)
    3. 在构建设置中选择所需的 Swift 语言版本

    4. 在构建设置中,添加(不要替换):NO运行时搜索路径

      如果您不小心替换,并使用了 embedded frameworkXPC will crash on launch

  4. 在您的扩展目标中:

    1. @loader_path/../../../../Frameworks 以便它可以看到协议。

    2. 创建连接,使用您的 XPC 目标的 import MyAppXPCService 包标识符

      serviceName
    3. 致电您的 XPC 服务:

      private let connection = { () -> NSXPCConnection in
        let connection = NSXPCConnection(serviceName: <#"com.example.MyAppXPCService"#>)
        connection.remoteObjectInterface = NSXPCInterface(with: MyAppXPCServiceProtocol.self)
        return connection
      }()
      

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

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...