无法调试嵌入在 Objective-C 应用程序中的 Swift 模块/框架
Posted
技术标签:
【中文标题】无法调试嵌入在 Objective-C 应用程序中的 Swift 模块/框架【英文标题】:Cannot debug Swift module/framework embedded in Objective-C app 【发布时间】:2017-01-20 21:57:23 【问题描述】:替代标题(帮助搜索)
无法在 Xcode 8 中调试链接到 Objective-C 应用程序的 Swift 2.3 框架error in auto-import: failed to get module 'XYZ' from AST context
Xcode 8 Xcode 8 无法调试 Swift 框架warning: Swift error in module <XYZ>
解决方法; Xcode Debugger 不能调试仅用 Objective-C 编写的应用程序,但只能与仅用 Swift 编写的框架链接。 (28312362)
我有一个用 Objective-C 编写的应用程序,它链接到一些用 Swift 2.x 编写的模块(框架)。
问题
一切(调试等)在xcode7 中工作正常,但是当移动到xcode8 并更新模块以使用swift2.3 时,我无法调试模块。
LLDB 报告了这些错误:
warning: Swift error in module XYZ.
Debug info from this module will be unavailable in the debugger.
error: in auto-import:
failed to get module 'ABC' from AST context
如果我将模块链接到在 Swift 2.3 中构建的应用程序,则不会发生这种情况。
【问题讨论】:
【参考方案1】:对我来说,这既简单又痛苦又耗时:
import SDWebImage
问题出在,
因为其中一个框架已经包含了 SDWebImage(我看不到它),而该框架恰好是 Objective-C,而应用程序是 Swift。
我还将 SDWebImage 添加到项目中,因为我在我编写的类中使用它,而这造成了 Xcode 调试器无法处理的混乱。
所以基本上,确保你没有以任何方式重复任何东西,我会检查常见的东西,例如 SDWebImage。
【讨论】:
我遇到了完全相同的问题,感谢您指出这一点。 @Tim Friedland 与 JSON 模型框架同样的问题感谢您的回答 是的完美答案.. 节省我的大量时间。谢谢@蒂姆弗里德兰 就我而言,我使用的是 SDWebImage 和 FirebaseUI(它依赖于 SDWebImage)并在 Swift 中导入。将这些导入移动到我的桥接头解决了我的问题。【参考方案2】:使用 fr v 代替 po 进行调试
更多调试 https://www.codeproject.com/Articles/1181358/Debugging-with-Xcode
【讨论】:
fr v
代表“帧变量”。更多信息请访问LLDB Debugging Guide
似乎不是一个解决方案,因为框架变量无论如何你都可以在控制台的左侧面板上看到它没有所有必要的输出。【参考方案3】:
我在 WWDC 2017 上与一位名叫 Sean 的 Apple 工程师讨论了这个问题。
我的团队花了数周时间试图解决这个问题,结果它成为 Apple 编译器上的一个错误,我们自己永远无法解决这个问题。此外,它有一个非常简单的解决方法。
编译标志从框架和项目聚合的方式恰好存在一个错误,“纯 Objective-C”项目“激活”它。
解决方案:在您的 Objective-C 项目中添加一个单独的空 Swift 文件(“Whatever.swift”或其他),使其不再是纯objective-c(new->file->Swift 文件,不要'不创建桥接头。该文件将仅包含 Foundation 的导入)。
就是这样。问题解决了。
【讨论】:
你是否碰巧有一个与此相关的 rdar 或 Swift 错误编号? 要修复在 Swift 中只有测试的项目的调试,您仍然需要添加一个针对该项目的空 Swift。仅添加 Swift 测试文件是不够的。以防其他人遇到此解决方案并且只想用 Swift 编写测试。【参考方案4】:tl:dr
在“构建设置”下为您的应用目标添加用户定义的设置。
SWIFT_VERSION = 2.3
更多信息
我不确定这是 Xcode 8 的错误还是 Apple 的政策(试图强制开发人员使用 Swift 3.0?)。但是...默认情况下,Xcode 8 会安装标准 Swift 运行时库的 Swift 3.0 版本。
在使用 LLDM 进行调试时,Swift 2.3 模块无法加载(进入 Swift 3.0 运行时)。
强制应用使用 Swift 2.3(或 Apple 所称的旧版 Swift),解决了这个问题。
Xcode 公开了 Swift 应用程序的此设置,但您必须为 Objective-C 应用程序手动添加它。
进一步的建议
尽快将您的 Swift 2.3 代码移植到 Swift 3.0,Apple 不会在很长时间内支持 2.x。
【讨论】:
Xcode 8.0 将尝试确定您使用的 Swift 版本并选择合适的工具链。您的项目设置方式正在破坏该检测。例如,Xcode 将为纯 ObjC 项目选择可用的最新工具链,恰好也是 Swift 3.0 工具链。例如,也许 Xcode 没有查看依赖的子项目或纯 ObjC 目标的目标以查看其中是否有任何 Swift?这似乎值得提交一个错误。 出于某种原因,这对我们不起作用。显式设置swift_version
(在 8A218a 中标记为“使用旧版 Swift 语言版本”)不会影响结果。
@DavidLord "Use Legacy Swift Language Version" 是不同的,这是用来告诉 Xcode 你想使用 Swift 2.x 而不是 3.x,在上面的场景中,这将被设置在框架目标。 SWIFT_VERSION
应该在(Objective-C)应用程序目标上设置。希望这会有所帮助!
啊——确实!你描述的很多问题都适用于我们的纯 Swift 项目,但是我们在 Swift 模块中没有 Obj-C 链接。感谢您的问答,将继续试验(或者在我们迁移到 Swift 3 之前不使用 LLDB)。
“自动导入错误”这件事可能是一种一般诊断,可能代表任意数量的不同错误。我得到了同样的错误,但不是告诉我 哪个 模块导致它的消息,这让我怀疑这是一个完全不同的问题。我已经仔细检查了 swift_version 设置是否正确。【参考方案5】:
就我而言,我必须从构建设置文件中删除 Objective-C Bridging header
。我的桥接头文件没有做任何事情..所以没关系。
【讨论】:
【参考方案6】:我在 9.3 模拟器中尝试调试时遇到了 error in auto-import: failed to get module 'XYZ' from AST context
消息。切换到 10.2 模拟器解决了这个问题。
【讨论】:
【参考方案7】:我在使用 Carthage 构建框架时遇到了这个问题。尝试调试会打印错误,该错误引用了 Obj-C 框架依赖项。
我发现了这个blog post,它建议在我的项目中添加以下用户定义的构建设置:
用于调试:REMOVE_HEADERS_FROM_EMBEDDED_BUNDLES = NO
发布:REMOVE_HEADERS_FROM_EMBEDDED_BUNDLES = YES
这为我解决了这个问题。
【讨论】:
【参考方案8】:尝试重启 Xcode。就我而言,它解决了一个问题。
【讨论】:
【参考方案9】:在我的情况下,在修复错误后,LLDB 中报告的“C”代码中存在编译器错误 LLDB 重新开始工作。
【讨论】:
【参考方案10】:正如 Tim https://***.com/a/41876400/1840269 所建议的那样,我们问题的根本原因是重复问题。
我们有一个用于 SDWebImage 的 obj-c 包装器类别,用于 obj-c 和 Swift。 从 Swift 导入类别时,由于 SDWebImage pod 已经将其自身暴露为 Swift 模块,因此由于重新定义/重复导入,一切都崩溃了。
解决方案?我们将 obj-c 类别重新实现为 Swift 扩展 - 并通过在扩展前面添加 @objc
并从 obj-c 导入 #import "product-Swift.h"
文件来继续在 Swift 和 obj-c 中使用它。
也许从检查开始:https://developer.apple.com/library/content/qa/qa1947/_index.html。
【讨论】:
【参考方案11】:我只花了 2 天时间就一直通过 print 命令解决和调试。现在我遇到了问题:
我的项目在 Swift 中,我使用的 Objective-C 库与在 Swift 的 pod 中导入的相同(旧的 Objective-C 项目合并在这个项目中)并且正在使用 import IQKeyboardManager 以及 import "IQKeyboardManager.h" 标头作为好吧。冲突和删除标题最终解决了我的问题。 您可以在库中检查这种类型的重复性。
【讨论】:
以上是关于无法调试嵌入在 Objective-C 应用程序中的 Swift 模块/框架的主要内容,如果未能解决你的问题,请参考以下文章
沙箱化嵌入 AppleScript 的 Objective-C 应用程序
在“发布”构建配置中看不到在桥接头中导入的头,但在“调试”构建配置中可见