SPM固定版本仍报错:依赖不稳定版本问题排查求助
问题场景
我有一个主要基于CocoaPods构建的应用(包含内部和外部依赖),为了模块化和现代化改造,新代码采用SPM包开发,这些包也有自身依赖。当我将宿主应用固定到内部库的标记版本0.0.2 .. Next Minor(即0.0.2..<0.1.0)时,出现无法解释的依赖解析错误:
Failed to resolve dependencies Dependencies could not be resolved because root depends on '{ourLibrary}' 0.0.2..<0.1.0. '{ourLibrary}' >= 0.0.2 cannot be used because ... no versions of '{ourLibrary}' match the requirement 0.0.3..<0.1.0 and package '{ourLibrary}' is required using a stable-version but '{ourLibrary}' depends on an unstable-version package 'iglistkit'.
我有两处困惑:
- 错误信息似乎表示“无法使用0.0.2版本,因为没有0.0.3版本”,这可能是信息格式的Bug。
- IGListKit被判定为“不稳定版本”,该项目已有3年多未发布标记版本,因此
ourLibrary通过指定具体commit(501cccc6f03)引入它,这应该是最稳定的方式。ourLibrary的Package.swift中配置为:
.package(url: "https://github.com/Instagram/IGListKit", revision: "501cccc6f03"),
另外,ourLibrary通过git@github.com URL拉取,这可能引发其他依赖解析问题,是否与此报错相关?
问题解析与解决方案
1. 错误信息的歧义原因
SPM的依赖解析逻辑是:当你指定稳定版本范围(如0.0.2..<0.1.0)时,它会优先尝试匹配范围内的最新稳定版本。这里错误信息的表述确实有歧义,本质问题不是“找不到0.0.3版本”,而是:
ourLibrary的0.0.2是带有语义化版本标签的稳定版本- SPM要求稳定版本的包不能依赖不稳定版本的包
- 用commit哈希引用的IGListKit,在SPM规则里属于“不稳定版本”(只有带语义化版本标签的依赖才被认定为稳定)
因此SPM直接拒绝使用ourLibrary的所有稳定版本(包括0.0.2),错误信息的表述只是解析逻辑中的一个环节,并非核心原因。
2. IGListKit被判定为不稳定的本质
SPM对“稳定版本”的定义非常严格:只有带有语义化版本标签(如3.0.0、2.1.5)的发布版本才被视为稳定。即使你用了固定的commit哈希,只要没有对应版本标签,SPM就会判定这是不稳定依赖。而稳定版本的包(如ourLibrary的0.0.2)依赖不稳定包,违反了SPM的依赖规则,导致解析失败。
3. git@github.com URL的影响
这个SSH协议的URL不会直接导致当前的依赖解析错误,只要你的开发环境配置了正确的SSH密钥,能正常拉取ourLibrary仓库,就和本次报错无关。报错未提及权限或拉取失败的信息,因此可以排除这个因素。
可行解决方案
方案一:改用不稳定版本方式引用ourLibrary
放弃稳定版本范围的限制,直接引用ourLibrary的0.0.2对应的commit哈希,这样SPM不会将其视为稳定版本,也就不会检查依赖的稳定性:
.package(url: "git@github.com/xxx/ourLibrary.git", revision: "<0.0.2版本对应的commit哈希>"),
方案二:给IGListKit添加自定义语义化版本
- Fork IGListKit仓库到你的团队账号下
- 在你使用的
501cccc6f03commit上打一个自定义语义化版本标签(如3.0.0-custom) - 修改
ourLibrary的Package.swift,引用这个fork的版本标签:
.package(url: "https://github.com/your-team/IGListKit.git", from: "3.0.0-custom"),
这样IGListKit就被SPM认定为稳定版本,ourLibrary的稳定版本依赖它就不会触发错误。
方案三:将ourLibrary的版本标记为预发布版
把ourLibrary的0.0.2标签改为预发布版本格式(如0.0.2-alpha),这样SPM会将其视为不稳定版本,允许它依赖其他不稳定包。之后宿主应用可以通过预发布版本范围引用:
.package(url: "git@github.com/xxx/ourLibrary.git", .upToNextMinor(from: "0.0.2-alpha")),
内容的提问来源于stack exchange,提问作者Chris

