Swift Package运行预览报错:XCPreviewAgent因缺失Testing.framework崩溃
问题场景
我将所有快照测试依赖及封装的工具代码迁移至独立本地Swift Package,避免在多个需快照测试的Package中重复导入依赖。但运行SwiftUI预览时出现崩溃:
XCPreviewAgent crashed because "Testing.framework" is missing
该本地Package可正常构建,只要移除对它的导入,SwiftUI预览就能恢复正常。此Package依赖一款SwiftUI预览快照第三方库,而该库又依赖swift-snapshot-testing。
解决方案
1. 限制快照依赖的作用范围至测试目标
在本地快照Package的Package.swift中,将所有快照相关依赖(包括预览快照库、swift-snapshot-testing)仅添加到测试目标的依赖列表,主目标不引入任何测试类依赖。因为SwiftUI预览会加载主目标的所有依赖,而Testing.framework是测试环境专属框架,主目标引入会导致预览Agent无法找到它。
示例修改:
let package = Package( name: "SnapshotTools", products: [ .library(name: "SnapshotTools", targets: ["SnapshotTools"]), ], targets: [ .target(name: "SnapshotTools", dependencies: []), // 主目标无测试依赖 .testTarget( name: "SnapshotToolsTests", dependencies: [ "SnapshotTools", // 在此添加所有快照相关依赖 .package(url: "https://github.com/doordash-oss/swiftui-preview-snapshots", from: "1.0.0"), .package(url: "https://github.com/pointfreeco/swift-snapshot-testing", from: "1.15.0") ]), ] )
2. 拆分Package代码结构
如果快照Package中存在需要在主项目中调用的工具代码(比如快照配置、UI扩展),将这部分代码放在主目标;把实际执行快照测试的逻辑放在测试目标。这样主目标不会携带测试框架相关依赖,SwiftUI预览可正常加载。
3. 用条件编译排除预览环境的Package导入
在主项目中导入本地快照Package时,通过条件编译跳过预览环境:
#if !XCODE_PREVIEWS import SnapshotTools #endif
这样SwiftUI预览加载时不会导入该Package,从根源避免依赖问题。
原因分析
SwiftUI预览的XCPreviewAgent运行在特殊环境中,不会加载测试专用框架(如Testing.framework)。而你的本地快照Package主目标引入了依赖Testing.framework的库,导致预览Agent尝试加载不存在的框架,最终触发崩溃。正常构建流程会正确引入测试框架,所以Package本身可以正常编译。
内容的提问来源于stack exchange,提问作者Lucas van Dongen

