混合使用Objective-C和Swift框架中标有@objc的Swift类没有被添加到“-Swift.h”头文件中。

3

我正在尝试将一个旧的静态链接库转换为框架。在静态库中混合了swift和objective c,所有头文件都生成正确。但是,切换到框架目标并添加用@objc头标记的swift文件时,该类不会添加到-Swift.h头文件中。我可以导入头文件,但找不到swift类。这是在Xcode 10.2中进行的,使用了Swift 4.2和5.

在混合Objective C / Swift框架目标中,有没有任何特定的XCode设置会影响*-Swift.h头文件的生成?


2
你做错了什么。 - Amin Negm-Awad
@AminNegm-Awad,那是一个显而易见的评论,问题是“我可能做错了什么”。 - JDL
1
@AminNegm-Awad,如果我可以提供更多细节来使问题更好,请说明。在搜索了所有可用的问题后,我已经提供了我认为相关的细节。如果你对XCode的了解不足以理解问题或可能的解决方案,请随时跳过这个问题。实际上,目前的问题是,“在混合Objective C/Swift框架目标中,是否有任何特定的XCode设置会影响*-Swift.h头文件的生成?” - JDL
我并没有说这不是问题,也没有说它没有解决方案。我说的是,这是你可以在SO上期望得到的答案。你做不得更好吗?“寻求调试帮助的问题[...]必须包括[...]在问题本身中重现所需的最短代码。”从创建包含问题的新项目开始。如果它不包含错误,请将新项目与现有项目进行比较。在许多情况下,问题会神奇地消失。 - Amin Negm-Awad
@AminNegm-Awad,这不是寻求代码“调试帮助”的问题,而是寻求对构建系统机制和影响它的设置的理解的问题。 - JDL
1
@AminNegm-Awad,Xcode中似乎只有4-6个设置会影响模块生成,这对我来说并不算“广泛”。无论如何,在经过大量调试和阅读构建系统相关资料后,我已经发布了一个可能的解决方案。 - JDL
2个回答

2
我有类似的问题。在我的情况下,这是Xcode 10.2中已知的问题:

https://developer.apple.com/documentation/xcode_release_notes/xcode_10_2_release_notes

如果您正在构建一个包含Swift代码的框架,并使用lipo创建支持设备和模拟器平台的二进制文件,则还必须组合每个平台生成的Framework-Swift.h头文件,以创建支持设备和模拟器平台的头文件。在我的情况下,我只需要将Carthage更新到最新版本0.33.0即可。

2
问题似乎是苹果的新构建系统、编译时设置的期望和项目设置中相互依赖的数量的组合问题。
新的构建系统可以并行运行Swift编译。当有多个混合Objective C和Swift的库/框架依赖时,编译器似乎无法及时生成-Swift.h文件。在静态库中,-Swift.h文件似乎是在Swift编译过程的最后生成的,这意味着它们不能在Objective C编译发生时被用于Objective C文件。在生成框架时,编译器似乎会在编译过程的开始生成头文件,并且Swift文件没有完全编译,因此-Swift.h文件不会与Objective C类接口和协议适当地生成。
这意味着我们不能依赖“目标依赖项”正确地构建依赖项目。
那么,如何构建我们的混合Objective C和-Swift.h的.framework而不需要大量手动脚本?
以下是我发现可行的技巧:
1.使用旧的构建系统。使用新的构建系统时,尝试合并静态库文件的模块映射时会出错,无论*-Swift.h文件是否存在。
2.通过将其包装在静态库中来创建您的框架:
- 给它们相同的产品名称和模块名称。 - 在框架构建中添加一个.Swift文件,以便它有东西可以编译,并将Swift库链接起来。 - 在框架中链接静态库。 - 将所有必要的头文件添加到框架的公共头文件中。 - 将所有公共头文件添加到总头文件中。 - 使用运行脚本阶段将*-Swift.h文件从静态库构建复制到框架产品后编译。 - 对于包含*-Swift.h的任何公共头文件,您可能需要对头文件进行后处理,并用适当的框架导入替换*-Swift.h导入,即。由于总头文件中可能存在循环导入,不建议这样做。
3.在构建应用程序目标之前,手动先构建框架目标。
以下是一个示例脚本,用于在编译后复制*-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编译模式标记为“整个模块”似乎对此问题有积极影响,但我尚未完全测试。

(原始回答:Original Answer)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接