如何在仅包含binaryTargets(XCFrameworks)的Swift Package中打包子依赖
解决方案
完全可以实现,问题出在Package.swift的配置不符合SPM的依赖传递规则。
问题根因
SPM 中binaryTarget本身不支持直接配置依赖,且你仅在包级声明了SubDependencyPackage依赖,没有将依赖和对外暴露的目标做绑定,因此上层引入WrapperPackage时不会自动拉取子依赖。
具体修改步骤
- 修正包依赖的name参数,当前声明的name带
.git后缀是错误的,需要和子依赖包的名称一致。 - 给每个XCFramework的二进制目标套一层普通的wrapper目标,将二进制依赖和子依赖都绑定到这个wrapper目标上。
- 新增对应的目录结构,在项目根目录下创建
Sources/ObjectiveCFramework1和Sources/ObjectiveCFramework2两个文件夹,每个文件夹下随便放一个占位文件(比如空的.h头文件)即可,用于SPM识别普通目标。
修改后完整的Package.swift代码
// swift-tools-version:5.3 import PackageDescription let package = Package( name: "WrapperPackage", platforms: [.iOS(.v13)], products: [ .library(name: "ObjectiveCFramework1", targets: ["ObjectiveCFramework1"]), .library(name: "ObjectiveCFramework2", targets: ["ObjectiveCFramework2"]), ], dependencies: [ // 修正name参数,和子依赖包的name保持一致 .package(name: "SubDependencyPackage", url: "git@github.com:user/SubDependencyPackage.git", .branch("main")), ], targets: [ // 原二进制目标重命名,加Binary后缀区分 .binaryTarget(name: "ObjectiveCFramework1Binary", path: "XCFrameworks/ObjectiveCFramework1.xcframework"), // 新增wrapper目标,绑定二进制依赖和子依赖 .target( name: "ObjectiveCFramework1", dependencies: [ "ObjectiveCFramework1Binary", .product(name: "SubDependencyPackage", package: "SubDependencyPackage") ], path: "Sources/ObjectiveCFramework1", publicHeadersPath: "." ), // 第二个框架同理配置 .binaryTarget(name: "ObjectiveCFramework2Binary", path: "XCFrameworks/ObjectiveCFramework2.xcframework"), .target( name: "ObjectiveCFramework2", dependencies: [ "ObjectiveCFramework2Binary", .product(name: "SubDependencyPackage", package: "SubDependencyPackage") ], path: "Sources/ObjectiveCFramework2", publicHeadersPath: "." ), ] )
额外注意事项
- 打包原Objective-C Framework为XCFramework时,要确保模块映射文件
module.modulemap中已经正确声明了对SubDependency的依赖,不要写死依赖的本地路径 - 修改配置后测试时,先清理Xcode缓存(快捷键
Command+Shift+K),再重置SPM缓存(Xcode菜单栏 > File > Packages > Reset Package Caches),避免旧缓存干扰测试结果
内容的提问来源于stack exchange,提问作者JimmyJammed
相关产品推荐
相关产品推荐

