基于XCFramework创建Swift Package时.bundle是否应包含在xcframework内
核心结论
你遇到的运行时找不到资源的核心原因是:SPM 的 binaryTarget 仅会自动解析并嵌入zip包中的XCFramework产物,同压缩包内的独立.bundle文件会被直接忽略,不会被拷贝到最终App包中。最优解决方案是将.bundle放入XCFramework内部,无需额外配置即可正常加载。
方案1:将资源bundle嵌入XCFramework内部(最推荐)
这是苹果原生支持、适配性最好的方案,操作步骤如下:
- 拆开XCFramework的目录结构,找到所有平台对应的framework子目录,常见路径示例:
- iOS真机对应
MyPackage.xcframework/ios-arm64/MyPackage.framework - iOS模拟器对应
MyPackage.xcframework/ios-arm64_x86_64-simulator/MyPackage.framework
- iOS真机对应
- 将
MyPackage.bundle拷贝到上述每个平台的MyPackage.framework根目录下 - 重新打包XCFramework为zip文件,计算新的checksum更新到Package.swift即可
- 需要配套修改XCFramework内部的资源查找逻辑,不要直接从主Bundle读取资源,改为先查找framework自身的Bundle,再读取内部嵌入的资源bundle,Swift示例代码:
// 先获取当前framework对应的Bundle let frameworkBundle = Bundle(for: MyPackageClass.self) // MyPackageClass替换为框架内部任意公开类 // 读取framework内嵌入的资源bundle guard let bundleUrl = frameworkBundle.url(forResource: "MyPackage", withExtension: "bundle"), let resourceBundle = Bundle(url: bundleUrl) else { fatalError("资源bundle加载失败") } // 后续所有资源都从resourceBundle加载,比如图片读取示例 let image = UIImage(named: "target_icon", in: resourceBundle, with: nil)
方案2:拆分SPM Target(不修改XCFramework的备选方案)
如果不方便修改XCFramework的打包逻辑,可以通过拆分Target的方式让SPM自动处理独立资源bundle:
- 将
MyPackage.bundle放到Swift Package的本地源码目录,或上传到单独的可访问地址 - 修改Package.swift配置,新增一个普通Target用于承载资源,同时依赖二进制XCFramework目标,示例配置:
let package = Package( name: "MyPackage", products: [ .library(name: "MyPackage", targets: ["MyPackageWrapper"]), ], targets: [ .binaryTarget( name: "MyPackageBinary", url: "HOST/MyPackage.xcframework.zip", checksum: "CHECKSUM" ), .target( name: "MyPackageWrapper", dependencies: ["MyPackageBinary"], resources: [.copy("MyPackage.bundle")] // 此处填写bundle文件的相对路径 ) ] )
- 对外暴露
MyPackageWrapper作为引入目标即可,SPM会自动将资源bundle拷贝到App产物中。
内容的提问来源于stack exchange,提问作者Heuristic
相关产品推荐
相关产品推荐

