症状: Xcode 26.6 Swift Package Manager 解析失败,常见表现是 package resolution、missing package product 或依赖版本突然变化。
最快解法: 不要一开始就删除全部缓存;先固定 Xcode、Package.resolved 与解析命令,再分别验证版本图、Git 访问和缓存状态。只有同一仓库始终无法恢复稳定基线时,才考虑重建环境。
这篇文章适合 3 类人:升级到 Xcode 26.6 后遇到依赖异常的独立开发者;使用私有 Swift Package 并在远程 Mac 上运行 xcodebuild 的开发者;维护常驻 iOS 打包机、需要避免重复下载或意外更新依赖的小团队。
最后更新于 2026 年 8 月 23 日。版本信息核实自 Apple Developer 发布记录、Xcode 26.6 Release Notes、Apple 持续集成文档和 Swift Package Manager 官方文档。Xcode 26.6 于 2026 年 6 月 25 日发布;Xcode 27 在当前核查时仍为 Beta,不应作为生产构建基线。 (developer.apple.com)
解析基线
先确认你遇到的到底是哪一层错误
“解析失败”不是所有依赖错误的统称。你需要先把故障分成 4 个状态:
- 依赖解析:版本约束无法同时满足,或 Package.resolved 中的版本已经不再符合 Package.swift。
- 源码检出:版本已经确定,但仓库无法连接、认证失败或无法下载。
- Package Product 绑定:包已解析,但项目引用的产品名、包名或 Target 依赖不匹配。
- 编译与 Archive:依赖已加载,真正失败发生在 Swift 编译、链接、签名或归档阶段。
Swift Package Manager 会根据依赖声明和版本要求确定可用版本;Package.resolved 记录最终解析结果。对于应用项目,它通常位于 .xcodeproj 或 .xcworkspace 相关目录中。(developer.apple.com)
先分别保存图形界面和命令行结果:
xcodebuild -version
xcode-select -p
xcodebuild -list -workspace "<WORKSPACE_PATH>"
xcodebuild -resolvePackageDependencies \
-workspace "<WORKSPACE_PATH>" \
-scheme "<SCHEME_NAME>"
图形界面中执行一次 File > Packages > Resolve Package Versions,再运行命令行解析。记录以下字段:
| 指标 | 需要记录的内容 | 判断用途 |
|---|---|---|
| Xcode 入口 | xcodebuild -version、xcode-select -p |
排除调用了旧版或 Beta |
| 项目入口 | .xcodeproj 或 .xcworkspace |
排除打开了错误工程 |
| 解析结果 | 首条有效错误、包名、版本 | 区分版本图与仓库问题 |
| 执行上下文 | 用户、当前目录、环境变量 | 解释本地与远程差异 |
| 前后对照 | 修复前、修复后的脱敏日志 | 确认问题是否真的消失 |
命令中的路径、项目名、仓库地址、账号和凭据都应替换为占位符。日志里不要保留 Token、SSH Key、用户名或私有主机名。
版本图与锁定文件
Package.resolved 的边界
对于作为最终构建目标的应用项目,Package.resolved 通常应该提交到 Git。Apple 的持续集成文档明确建议提交该文件,并在直接使用 xcodebuild 时关闭自动解析,以便构建使用文件中记录的依赖版本。(developer.apple.com)
但这个规则有一个容易被忽略的边界:如果你维护的是一个被其他项目引用的 Swift Package,库项目自己的 Package.resolved 不会替下游应用锁定版本。下游项目解析时,仍会依据自己的 Package.swift 和 Package.resolved 决定依赖关系。(github.com)
排查时执行:
git status --short
git diff -- "<PACKAGE_RESOLVED_PATH>"
grep -n '"identity"\|"version"\|"location"' "<PACKAGE_RESOLVED_PATH>"
重点看 4 类异常:
- 切换分支后,Package.swift 已改变,但 Package.resolved 没有同步更新。
- 合并冲突留下重复记录,或者包身份、地址发生变化。
- 自动更新脚本在构建前执行了解析或更新操作。
- 锁定版本不再满足当前 Package.swift 的版本约束。
在稳定构建环境中,建议把“更新依赖”和“使用依赖”分成两个明确动作。日常开发可以主动更新并审查变更;远程 Mac 或自动打包任务应优先复现仓库已提交的锁定版本,而不是每次执行时重新选择版本。
xcodebuild 的固定入口
可以把解析和构建拆开,先观察解析结果:
xcodebuild -resolvePackageDependencies \
-workspace "<WORKSPACE_PATH>" \
-scheme "<SCHEME_NAME>" \
-clonedSourcePackagesDirPath "<SOURCE_PACKAGES_PATH>"
确认解析成功后,再使用固定入口构建:
xcodebuild \
-workspace "<WORKSPACE_PATH>" \
-scheme "<SCHEME_NAME>" \
-configuration Release \
-destination "generic/platform=iOS" \
-disableAutomaticPackageResolution \
build
-disableAutomaticPackageResolution 的作用是避免构建过程自动改变依赖解析结果。它不能修复失效的锁定文件,也不能替你解决私有仓库认证;它只是把“依赖版本选择”从隐式动作变成可审计的构建前提。(developer.apple.com)
仓库访问与凭据
公开包和私有包要分开判断
公开 Swift Package 失败时,优先检查 Git URL、DNS、代理和仓库是否仍可访问。私有包则要继续检查 SSH 主机指纹、密钥是否被当前用户加载、仓库权限以及远程任务能否读取对应配置。
不要只测试:
git clone "<REPOSITORY_URL>"
还要在与构建任务相同的用户和工作目录下测试:
whoami
pwd
ssh-add -l
ssh -T git@"<GIT_HOST>"
git ls-remote "<REPOSITORY_URL>" "<TAG_OR_BRANCH>"
如果 git ls-remote 失败,问题尚未进入 Swift Package Manager 的版本图阶段。先修复连接或认证,再继续看 Package.resolved。
Apple 文档特别提示,直接运行 xcodebuild 时,项目可能需要使用 SSH 形式的 Git URL,并配置对应的 SSH 凭据;如果依赖私有仓库,构建环境必须明确获得访问权限。(developer.apple.com)
注意:交互式终端里的 SSH Agent 配置,不等于无人值守任务里的 SSH Agent 配置。远程任务可能没有加载你的 Shell 配置文件,也可能使用不同的执行用户。
内置 Git 与系统 Git 的差异
在本地终端中,which git 显示的程序不一定就是 Xcode 解析依赖时使用的工具链。不同入口可能读取不同的环境变量、SSH 配置和凭据来源,因此“终端能拉取”不能直接证明“Xcode 能解析”。
你可以把以下信息加入脱敏诊断日志:
| 检查项 | 本地终端 | 远程任务 | 结果解释 |
|---|---|---|---|
| 执行用户 | <LOCAL_USER> |
<BUILD_USER> |
不同用户可能没有相同密钥 |
| 工作目录 | <LOCAL_DIR> |
<BUILD_DIR> |
可能读取不同工程或锁定文件 |
| Git 入口 | <GIT_PATH> |
<GIT_PATH> |
工具链和配置来源可能不同 |
| SSH 配置 | <SSH_CONFIG> |
<SSH_CONFIG> |
主机指纹、Agent、权限需一致 |
| 代理变量 | <HTTP_PROXY> |
<HTTP_PROXY> |
远程网络可能无法访问仓库 |
所有占位符都应在实际内部记录中替换为脱敏值,不要把真实凭据写入构建日志。
缓存层与依赖图
不要把所有缓存当成同一个目录
Swift Package 相关故障至少涉及仓库缓存、依赖检出目录、DerivedData 和构建产物。它们的故障范围不同:
- 仓库缓存:更接近远程 Git 拉取和版本检出。
- 依赖检出目录:反映当前任务实际拿到的源码版本。
- DerivedData:包含项目索引、编译中间产物和部分构建状态。
- 构建产物:可能掩盖源码、链接或 Archive 阶段的问题。
全部删除会带来重复下载、重新索引和更长的恢复路径,还可能让一次偶发的网络问题变成新的冷缓存问题。正确做法是先保留现状,记录错误,再逐层重置。
建议按这个顺序操作:
- 使用现有缓存再次执行解析,保存日志。
- 复制或记录当前 Package.resolved 和检出目录状态。
- 只清理与当前错误层级对应的目录。
- 重新执行
-resolvePackageDependencies。 - 比较清理前后的首条有效错误。
- 解析稳定后,再测试普通构建和 Archive。
Xcode 的官方问题排查文档也建议通过构建报告和日志定位失败动作,并确认项目或 Workspace 使用了正确的环境,而不是直接把所有状态视为缓存问题。(developer.apple.com)
Package Product 与二进制依赖
如果日志显示包已经解析成功,但出现 missing package product,不要继续删除 Package Cache。此时应检查:
- Target 中引用的 Product 名是否仍存在。
- 包身份和 Product 名是否混淆。
- 当前 Scheme 是否包含正确的 Target。
- 本地包覆盖是否只在某个分支或某个用户环境中存在。
- 二进制依赖是否支持当前平台和架构。
- 二进制包的 checksum 是否发生变化。
二进制依赖只支持其发布时包含的平台和架构。Xcode 在解析或更新时,也会校验二进制包的 checksum;校验异常应作为包内容或版本发布问题处理,而不是网络问题。(developer.apple.com)
如果只有某个 Scheme 失败,建立一个最小复现项目:保留一个 Target、一个 Package Product 和同一份 Package.resolved。最小项目成功而原项目失败,通常说明问题在项目结构、Target 绑定或 Workspace 配置,而不是仓库访问。
远程 Mac 验收
当本地可以构建、远程 Mac 却失败时,先不要迁移项目。你需要验证远程环境是否具备可重复性。
Xcode 26.6 的官方要求包括 Swift 6.3、对应平台 SDK,以及 macOS Tahoe 26.2 或更高版本。生产构建应确认远程主机满足版本要求,并且不要把 Xcode 27 Beta 当成稳定构建工具。(developer.apple.com)
五步验收流程
-
固定提交
使用同一个 Git 提交、同一份 Package.resolved 和同一套项目文件。 -
固定 Xcode 入口
记录xcodebuild -version、xcode-select -p和执行用户。 -
单独解析依赖
运行xcodebuild -resolvePackageDependencies,不要直接从 Archive 失败日志倒推解析问题。 -
执行普通构建
使用-disableAutomaticPackageResolution,确认已解析依赖可以被目标 Target 正常编译。 -
执行 Archive 和恢复测试
主机重启、清理工作目录、重新拉取仓库后,再重复解析、构建和 Archive。
决策条件如下:
- 若同一提交在本地和远程 Mac 使用同一 Xcode、同一 Package.resolved,且私有仓库认证结果一致,则保留当前环境,继续修复项目或依赖图。
- 若只有远程 Mac 失败,且失败集中在执行用户、SSH、Git 提供方或工作目录,则先修复环境差异,不要重写 Package.swift。
- 若清理单层缓存后错误变化明确,则继续针对该层处理,并保留前后日志。
- 若冷缓存、热缓存、主机重启和重新拉取后都无法得到稳定结果,则考虑重建环境。
- 若本地机器无法长期保留稳定的 macOS、Xcode 和依赖缓存,则把远程 Mac 作为常驻打包机候选,并先用真实项目完成 Archive 验收。
如果你正在搭建远程构建流程,可以继续参考 远程 Mac 上的 xcodebuild 自动构建配置,并结合 iOS 打包机依赖缓存维护思路 设计清理和恢复策略。对于私有仓库,还应单独规划 远程 Mac 的私有 Git 认证环境,不要把凭据配置混在项目脚本里。
当前方案与远程 Mac
如果你现在依赖个人电脑完成所有解析和 Archive,真实缺点通常有 3 个:本地设备关机后无法继续执行;开发环境容易被升级、分支切换或手动清理改变;私有仓库凭据和缓存状态也可能只存在于你的交互式账户中。临时借用 Windows 或 Linux 主机则无法直接运行完整的 Xcode 工具链,虚拟化方案还会增加系统版本、磁盘和设备访问限制。
当你的问题主要来自“缺少一台长期在线、版本固定、可由无人值守任务访问的 Mac”,租用 MACCOME 的远程 Mac 会比临时改造个人电脑更容易做环境验收。你仍应先用真实项目验证 Package.resolved、私有仓库解析和 Archive;如果需求是长期满负载编译,或必须连接本地真机、专用硬件接口,自购设备可能更合适。需要临时算力、短期测试环境或常驻 iOS 打包机时,再根据构建频率选择 MACCOME 的远程 Mac 方案。