iOS Xcode SPM无法分解超类

时间:2019-10-21 13:35:02

标签: ios xcode swift-package-manager

我的应用程序由许多项目(框架)组成,每个主要功能一个,而一个通用框架则包含我需要通过多个功能访问的各种内容。

我正在使用Xcode 11的Swift Package Manager添加依赖项。

公共框架包含一个RxSwift依赖项,我在整个项目中都会使用它。

当我尝试在任何功能框架中使用RxTest时遇到问题。

如果我通过SPM将RxTest直接添加到测试目标并运行测试,则会得到

  

无法从损坏的名称“其他类名称”中分解“类名称”的超类

还有许多

  

在“通用框架路径”和“测试目标路径”中都实现了类“类名”

所有这些类都与Rx有关。 “无法解贴失败”错误使测试崩溃,并且仅在尝试初始化RxTest类时发生。

如果我将RxTest添加到通用框架中,则测试可以正常运行,但是当我运行该应用程序时,我会得到

  

dyld:未加载库:@ rpath / XCTest.framework / XCTest

这是有道理的,因为我要在非测试框架中添加一个测试框架,而这并不是一件好事。

因此,基本上,我无法获得测试和应用都能正常运行的配置。应用程序运行或测试运行。

我该如何工作?仅当我在测试目标上构建RxTest时,才可以将其包含在通用框架中吗?还是应该仅将RxTest包含在测试目标上,而我缺少一些配置?

3 个答案:

答案 0 :(得分:1)

具有SPM依赖关系的Xcode现在不能在多个相互依赖的目标中处理相同的SPM依赖关系。目前,每个依赖项仅需要位于单个目标中。我现在不知道为什么,但是如果没有提交,我会尝试进行更多调查并提交错误。

答案 1 :(得分:0)

您的问题很可能是库正在使用静态链接而不是动态链接。在SwiftPM中,您可以根据需要将库指定为静态库或动态库,也可以让构建系统决定大多数软件包的工作方式。 Xcode使用SwiftPM构建时似乎偏爱静态方法,这会导致您遇到构建问题。

如果您将Package.swift修改为使RxTest为动态库,它应该可以工作。您可以通过克隆RxSwift并修改以下行来轻松测试:

.library(name: "RxTest", targets: ["RxTest"]),

进入:

.library(name: "RxTest", type: .dynamic, targets: ["RxTest"]),

,然后将RxSwift的本地副本拖到Xcode项目浏览器中。 然后它将使用您的软件包的本地副本,而不是Xcode克隆的副本。

执行此操作后,可以将其链接到所需的任何目标,并且应该可以使用。如果确实能解决问题,那么您的长期解决方案很可能是

1)有一个叉子,可以将其简单地更改为动态库。

2)说服RxSwift社区,将其产品更改为动态版本或除默认版本外出售动态版本。

3)不要在多个地方使用RxTest或类似的东西。


还值得注意的是,Xcode 11.3和更早版本不支持使用动态Swift软件包进行归档。因此,如果沿着动态路线走下去,您将不得不等待Xcode 11.4。

答案 2 :(得分:0)

解决方法:

我有同样的问题。我的项目配置是:

  • 工作区
    • ProjectAppOne
      • AppTargetOne(嵌入并签名FrameworkTarget)
    • ProjectAppTwo
      • AppTargetTwo(嵌入并签名FrameworkTarget)
    • ProjectCoreFramework
      • FrameworkTarget
      • testsTareget
      • SPM依赖关系(包括RxSwift)

我的解决方法是:

  1. 复制 FrameworkTarget 并创建一个 FrameworkTargetT (确保两者都没有问题)。
  2. FrameworkTarget 仍用于构建应用程序目标,因此请确保这是导入应用程序目标中唯一使用的目标。
  3. 将RxTest添加到 FrameworkTargetT
  4. FrameworkTarget
  5. 中删除RxTest
  6. 设置测试@testable import FrameworkTagetT
  7. 调整 FrameworkTarget 以不运行testsTarget
  8. 设置 FrameworkTargetT 以运行 testsTarget
  9. 调整涉及测试目标的CI快速通道/脚本,并直接调用 FrameworkTarget

最后,项目结构如下:

  • 工作区
    • ProjectAppOne
      • AppTargetOne(嵌入并签名FrameworkTarget)
    • ProjectAppTwo
      • AppTargetTwo(嵌入并签名FrameworkTarget)
    • ProjectCoreFramework
      • FrameworkTarget
      • FrameworkTargetT
      • testsTareget
      • SPM依赖关系(包括RxSwift)

我认为这不是理想的解决方案,很容易在代码或测试中导入错误的框架,因此请仔细检查您是否对此感到满意。但是,当我们等待SPM团队对问题进行分类时,可以轻松使用和删除它。如果您已经有框架分隔的代码,这也很容易。

PS:您需要记住将每个新文件都添加到两个目标 FrameworkTarget FrameworkTargetT