我正在尝试将旧的静态链接库转换为框架。 在静态库中混合使用 swift 和 objective c,所有标头都会正确生成。 但是,切换到框架目标并添加带有 @objc 标头标记的 swift 文件时,该类不会添加到 -Swift.h 标头中。 我可以导入标头,但找不到 swift 类。 这是在 Xcode 10.2 中,并尝试使用 Swift 4.2 和 5。
XCode 中是否有任何特定的设置会影响混合 Objective C/Swift 框架目标中 *-Swift.h 标头的生成?
我也有类似的问题。就我而言,这是Xcode 10.2中的已知问题:
https://developer.apple.com/documentation/xcode_release_notes/xcode_10_2_release_notes
如果要构建包含 Swift 代码的框架,并使用 lipo 创建同时支持设备和模拟器平台的二进制文件,则还必须组合为每个平台生成的 Framework-Swift.h 标头,以创建同时支持设备和模拟器平台的标头。(48635615) ...
就我而言,我所要做的就是将Carthage
更新到最新版本0.33.0
问题似乎是苹果的新构建系统、他们在编译时设定的期望以及项目设置中相互依赖关系的数量的组合。
新的构建系统并行运行 Swift 编译。 当有多个混合了 Objective C 和 Swift 的库/框架依赖项时,编译器似乎无法按时生成 -Swift.h 文件。 在静态库中,-Swift.h 文件似乎是在 Swift 编译过程结束时生成的,这意味着它们的生成速度不够快,无法在 Objective C 编译发生时使用。 生成框架时,编译器似乎在编译过程开始时生成标头,并且 Swift 文件未完全编译,并且 -Swift.h 文件未使用 Objective C 类接口和协议正确生成。
这意味着最终意味着我们不能依赖"目标依赖项"来正确构建依赖项目。
那么我们如何在没有大量手动脚本的情况下构建混合 Objective C 和 -Swift.h 的 .framework。
以下是我发现的可行的技巧。
- 使用旧的构建系统。使用新的构建系统时,当它尝试合并静态库文件的模块映射时会出现错误,指出无论 *-Swift.h 文件是否存在,它都找不到它。
- 通过以下方式使框架成为静态库的包装器来创建框架:
- 为它们提供相同的产品名称和模块名称。
- 添加单个 .Swift 文件到框架构建中,以便它有一些东西可以编译,并将链接 swift 库。
- 链接到框架中的静态库。
- 将所有必要的标头添加到框架的公共标头。
- 将所有公共标头添加到伞标头。
- 使用运行脚本阶段将 *-Swift.h 文件从静态库构建复制到框架产品编译后。 对于任何包含 *-Swift.h 的公共标头,
- 您可能需要对标头进行后处理,并将 *-Swift.h 导入替换为适当的框架导入,即 。不建议这样做,因为伞形标头中可能存在周期性导入。
- 运行清理时,请先手动生成框架目标,然后再生成应用程序目标。
下面是一个用于复制 *-Swift.h 文件构建后的示例脚本。
header_file="${TARGET_TEMP_DIR}/../${PRODUCT_MODULE_NAME}.build/DerivedSources/${PRODUCT_MODULE_NAME}-Swift.h"
header_dir="${BUILT_PRODUCTS_DIR}/${PUBLIC_HEADERS_FOLDER_PATH}"
mkdir -p "$DIR"
echo "copying $header_file $header_dir"
cp -f "$FILE" "$DIR"
更新
将所有模块 Swift 编译模式标记为"整个模块"似乎对这个问题有积极影响,但我还没有完全测试它。