【问题标题】:Reach swift code in static library from Objective-C in main target从主要目标中的 Objective-C 获取静态库中的 swift 代码
【发布时间】:2020-11-06 16:00:52
【问题描述】:

我想从主要目标中的 Objective-c 代码访问静态库中的 Swift 代码。

通常我必须将生成的 -swift.h 文件导入主目标中的静态库。但问题是Xcode在/DerivedData目录下的/Build文件夹中生成<ProductName>-Swift.h文件,而不是在常规的/include目录下。这意味着 Xcode 无法自动找到它。相反,唯一的解决方案似乎是将带有构建时复制脚本的-swift 复制到该位置。

这适用于动态框架,但我希望尽可能避免添加另一个动态框架的启动时间损失。

设置 (test project available here)

  1. 混合 Objc/Swift 主要目标

  2. 混合 Objc/Swift 静态库

问题

从主要目标中的 Objective-C 代码,到达静态库中的 swift 代码。 尝试导入静态库时遇到的错误是:

或者

尝试的解决方案

我发现的唯一解决方案是有一个 复制阶段脚本(建议 here)将生成的静态库的 -swift.h 标头复制到主要目标的位置可以找到。在我看来,这不是一个非常稳定的解决方案,因为它取决于 Xcode 在构建时放置此文件的内部工作原理。归档项目时位置也不同。

我试图在静态库中定义我自己的模块映射(如建议的here),但没有设法让它工作。最后我的模块还是没有被主目标找到。

【问题讨论】:

  • 我倾向于将库视为来自第 3 方,并将其移动到已知的库/标题位置。然后我会使用库并在我的主项目中包含路径来找到它。自动正确放置文件可能是库项目中构建后脚本的一部分。

标签: objective-c swift xcode static-libraries


【解决方案1】:

修复

我必须道歉 - 我第一次尝试非常匆忙,并没有真正阅读您尝试的解决方案。现在我有更多时间,我看到你按照我最初的建议做了。解决 Xcodeinner workings 的方法是在首选项中指定一个构建目录。我将其配置为MyBuild,您可以从下面的路径中看到。我在MyBuild 相对目录中搜索了该文件,并使用了我找到的第一个文件。这没问题,但也许其他一些位置会更好。

// This file cannot be found
#import "../../MyBuild/OperabilityProject/Build/Intermediates.noindex/OperabilityProject.build/Debug-iphonesimulator/StaticLibraryOperability.build/DerivedSources/StaticLibraryOperability-Swift.h"

编辑 - 使用环境变量

这里还有另一种方法,这次使用环境变量和来自https://gist.github.com/gdavis/6670468 的一点帮助。如您所见,选项很多。我用了BUILD_DIR,但对你来说DERIVED_FILES_DIR 看起来很有趣。

我将BUILD_DIR 包含在搜索路径中,如下面的屏幕截图所示。

然后我就可以通过如下方式访问它。

#include "../Intermediates.noindex/OperabilityProject.build/Debug-iphonesimulator/StaticLibraryOperability.build/DerivedSources/StaticLibraryOperability-Swift.h"

正如您所看到的,这仅适用于DEBUG,但至少对于RELEASE 是相同的,我认为这是更好的选择,因为您可以将配置保留在项目本地而不需要编辑您的(系统范围的)Xcode 配置,就像在第一个解决方案选项中一样。

【讨论】:

  • 感谢您提供翔实的解释,顺便说一句,为什么有时调试和发布模式会存在这种差异?
  • @zeytin ...谢谢!取决于您在这里指的是什么差异?但是 Debug 是为了测试并且包含很多 NSLog 的。发布进行了优化,去掉了调试符号,并且不应该包含任何 NSLog。在我的设置中,我有 Release #define NSLog xXxxxXx 或类似的荒谬的东西,以确保如果 NSLog 最终在 Release 中编译失败。但是,如果您正确使用#ifdef 和family,您就会将两个不同的程序合二为一。它易于维护,因为它是一个单一的源文件并且易于例如在 Debug 中使用 NSLog 记录大量内容,这会从 Release 中消失。
  • 我对这个解决方案的问题是它依赖于 Xcode 放置这个文件的位置。没有证件的东西。如果这发生了变化,那么这将停止工作。
  • 如果您使用选项 1,那么 定义它的放​​置位置。如果您使用选项 2,那么如果位置发生变化,环境变量也会发生变化,因此您应该被覆盖。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多