症狀 → 最快解法: Xcode 26.6 Swift Package Manager 解析失敗時,不要先刪除全部快取;先固定 Xcode、Package.resolved 與解析命令,再分別驗證版本圖、Git 存取及快取狀態。
適用條件: 只有遠端 Mac 或自動建置失敗時,優先檢查執行使用者、SSH、Git 設定與工作目錄;同一個提交在固定環境仍無法恢復穩定基線,才考慮重建環境。
最後更新於 2026 年 8 月 23 日;版本狀態核實自 Apple 的 Xcode 發佈記錄、Xcode 26.6 Release Notes 及 Apple、Swift Package Manager 官方文件。
這篇指南適合哪些建置問題
如果你在升級 Xcode 26.6 後遇到 package resolution 失敗、missing package product 或依賴版本異常,本文適合你。使用私有 Swift Package,並在遠端 Mac 透過 xcodebuild 建置專案的開發者,也可以直接照著執行。
若你維護常駐 iOS 打包機,重點不是「今天能否成功解析」,而是重啟主機、清空工作目錄或重新拉取程式碼後,是否仍能以同一組依賴完成建置與 Archive。
截至上述核實日期,Xcode 26.6 是 Apple 已發布的穩定版本;Xcode 27 仍屬 Beta。不要把預發布版本的論壇個案,當成 Xcode 26.6 的通用結論。
先建立可比較的解析基線
同時記錄圖形介面與命令列結果
先不要修改依賴版本,也不要執行全域清理。建立一份脫敏記錄,至少包括:
xcodebuild -version顯示的 Xcode 與 SDK 資訊。xcode-select -p指向的活動 Developer Directory。- 實際使用的
.xcodeproj或.xcworkspace。 - Scheme、建置組態,以及解析命令。
- 第一個真正的錯誤,而不是最後一行籠統的 exit code。
- 觸發解析的 Git 提交、分支與
Package.resolved版本。
命令中的專案名稱、路徑、帳號、主機名稱與憑證都改成 <PROJECT>、<WORKSPACE>、<REPOSITORY> 等佔位符。Token、SSH Key、私有網址和原始日誌不可直接貼到工單或文章中。
在 Xcode 中執行一次 Resolve Package Versions,再於相同工作目錄執行命令列解析。例如:
xcodebuild -resolvePackageDependencies \
-workspace "<WORKSPACE>.xcworkspace" \
-scheme "<SCHEME>"
若使用專案檔,將 -workspace 換成 -project "<PROJECT>.xcodeproj"。Apple 的 持續整合建置 Swift Package 與使用套件的 App 文件 可用來核對 CI 的入口與建置方式。
若圖形介面成功、命令列失敗,問題較可能落在 Shell、執行使用者、活動 Xcode 或 Git/SSH 設定。若兩者都失敗,才優先檢查版本圖、套件網址與存取權限。保留修復前後兩份日誌,否則你無法判斷某次清理究竟改變了什麼。
先分清楚四種狀態
「解析失敗」不等於所有套件問題。你要把狀態拆開:
- 依賴解析:版本約束是否能找到一組可行解。
- 原始碼檢出:Git 是否能連線、驗證並下載指定版本。
- 依賴圖與產品生成:套件是否產生預期的產品與 target。
- 連結 Package Product、編譯或 Archive:解析完成後,專案是否正確引用並通過編譯。
例如日誌已顯示套件成功 checkout,後面卻出現 Missing package product,這通常不應再從 DNS 或快取開始查。此時應檢查產品名稱、Target membership、Scheme,以及本地套件覆蓋。
先核對 Package.resolved 與版本圖
Package.resolved 應否提交到 Git
對需要可重現建置的 App 專案,通常應把 Package.resolved 納入版本控制,讓本地、CI 和遠端 Mac 使用同一組已解析版本。這不是把所有 Swift Package 的規則都套用到每種套件型別:被其他專案引用的 Swift Package 本身,通常不應把上層 App 的 Package.resolved 當作自己的版本鎖定檔。
先比較三個來源:
Package.swift中的套件網址與版本約束。- Xcode 專案或 Workspace 實際引用的套件。
Package.resolved中的身份、位置、版本或 revision。
Swift Package Manager 會依照依賴約束解析版本;可參考 Swift Package Manager 的版本解析說明。Apple 對套件依賴宣告的 Package.Dependency 文件 則可用來核對宣告方式。
切換分支或合併衝突後,特別檢查以下情況:
Package.resolved仍記錄已不符合Package.swift的 revision。- 同一套件因身份或網址格式不同而出現重複記錄。
- 自動更新腳本在建置前重新解析,覆蓋了倉庫內的鎖定結果。
- App 專案提交了鎖定檔,但 CI 使用另一個工作目錄或另一個檔案。
用 xcodebuild 固定解析入口
固定版本不代表把版本字串硬編碼到每一個命令。更重要的是讓命令使用正確的 Workspace、Scheme、提交和工作目錄,並避免每次任務自行更新依賴。
建議先在乾淨分支確認:
git rev-parse HEAD
git status --short
xcodebuild -version
xcode-select -p
xcodebuild -resolvePackageDependencies \
-workspace "<WORKSPACE>.xcworkspace" \
-scheme "<SCHEME>"
把輸出與 Package.resolved 一起保存。若自動流程在解析前執行套件更新、刪除鎖定檔或重新產生專案,先停用這些步驟,再重跑基線。你要比較的是同一提交、同一鎖定檔、同一命令的結果,而不是「某次剛好成功」的結果。
把公開套件與私有套件分開驗證
先定位連線、認證還是拉取階段
公開套件與私有套件同時失敗,才比較像活動 Xcode、DNS 或整體網路問題。只有私有套件失敗時,依序驗證:
- Git URL 是否與
Package.swift或專案記錄完全一致。 - DNS、代理與防火牆是否允許連線到
<GIT_HOST>。 - SSH 主機指紋是否已被執行使用者信任。
- SSH Key 是否在該工作階段載入。
- 該帳號是否有讀取倉庫與指定 revision 的權限。
- 失敗是在建立連線、完成認證,還是拉取物件時發生。
不要在指令列中直接放入真實密碼或 Token。診斷輸出只保留 <GIT_HOST>、<ACCOUNT>、<REPOSITORY> 和錯誤類型。
為什麼本地成功,遠端 Mac 卻失敗
本地與遠端 Mac 可能不是同一個執行使用者,也不一定讀取同一套 Git 和 SSH 設定。互動式登入 Shell 可讀到你的 ~/.ssh/config,無人值守工作卻可能使用另一個 Home 目錄;SSH agent、known_hosts、代理環境變數也可能不同。
此外,xcodebuild 使用的 Git 執行路徑與你手動輸入 git 時的路徑可能不同。不要只在互動式終端驗證一次,就推論自動任務也具備相同權限。Apple 的 Xcode 常見設定與建置問題說明 可作為環境檢查的官方參考。
在遠端 Mac 上,使用與排程任務相同的帳號和工作目錄,逐項記錄:
whoami
echo "$HOME"
git config --show-origin --list
ssh -G "<GIT_HOST>"
若 SSH 設定含有私密路徑或代理資訊,分享前必須脫敏。這一步的目標不是證明「SSH 指令能連線」,而是確認 Xcode 解析時能否以相同身份讀取相同倉庫。
依照故障範圍選擇快取動作
不要把所有快取當成同一層
常見目錄的影響範圍不同:
- Repository cache:保存遠端 Git 倉庫的下載資料。異常時可能影響重新取得 revision。
- Source packages checkout:保存已檢出的套件原始碼。刪除後通常需要重新下載。
- DerivedData:包含專案索引、編譯中間檔與部分建置狀態,不等於套件版本資料。
- 建置產物:可能包含可重用的編譯結果;清除後會增加重建成本。
- 簽名材料:憑證、Provisioning Profile、Keychain 項目不可因為套件解析問題而無差別刪除。
先比較現有快取與冷快取的解析結果,再決定重置哪一層。若現有快取失敗、冷快取成功,檢查快取內容或檢出狀態;若兩者都失敗,繼續查版本圖或 Git 存取。每次只改一層,並在日誌中記錄錯誤是否由「找不到 revision」變成「認證失敗」或其他狀態。
重置 Package Cache 後仍然失敗,並不代表需要反覆刪除快取。此時應回到 Package.resolved、私有 Git 權限、Xcode 選擇器及執行使用者。無差別清理只會造成重複下載,還可能讓你失去原本可比較的故障證據。
用最小專案確認產品與二進位依賴
解析成功後仍出現 Missing package product,檢查的對象已經改變。核對套件名稱、產品名稱、版本約束、本地套件覆蓋與 Scheme 引用。若使用二進位套件,再檢查 checksum、架構與 Xcode 是否能辨識該依賴;Apple 的 二進位依賴辨識文件 可作為核對依據。
若錯誤只在某個分支或 Scheme 出現,建立只保留一個 App target、同一份 Package.resolved 和最少套件的最小重現專案。結果可以這樣判讀:
- 最小專案也失敗:優先檢查 Xcode、Git 存取或套件本身。
- 最小專案成功,原專案失敗:優先檢查 Workspace、Target、Scheme 或本地套件覆蓋。
- 解析成功但 Archive 失敗:轉查簽名、架構、編譯設定與二進位依賴,不要繼續清理 Package Cache。
依條件決定修復、遷移或保留雙環境
使用以下分支作為決策工具:
- 若同一提交在圖形介面與命令列都能解析,且差異只出現在自動任務,選擇修正執行使用者、
HOME、SSH agent、Git 設定和工作目錄;不要重建整台 Mac。 - 若公開套件成功、私有套件失敗,選擇修正 Git URL、主機指紋、密鑰與倉庫權限;不要先刪除全部快取。
- 若冷快取與現有快取結果不同,先重置受影響的套件快取或檢出目錄,保留簽名材料與診斷日誌。
- 若
Package.resolved與約束不一致,先在受控分支重新解析、審查差異並提交正確鎖定檔;不要讓每次 CI 任務自動選取新版本。 - 若同一倉庫在固定版本、固定命令及固定執行使用者下仍無法重現成功,才考慮遷移或重建環境。
- 若本地穩定、遠端不穩定,先保留本地環境作為對照;遠端 Mac 通過重啟、清理工作目錄和重新拉取後的驗收,再決定是否移除雙環境。
遠端 Mac 的可重現建置驗收
遠端 Mac 不應只以一次成功解析作為合格標準。使用同一提交、同一 Package.resolved 和同一 xcodebuild 命令,連續驗證三個階段:
- 依賴解析完成,且日誌中的套件版本與鎖定檔一致。
- 一般建置完成,沒有把解析問題誤判成編譯問題。
- Archive 完成,並分開記錄簽名與套件相關錯誤。
接著在相同執行使用者下驗證工作目錄清理、重新拉取倉庫與主機重啟後的恢復能力。若重啟後 SSH agent、known_hosts 或 Git 設定消失,問題是環境初始化,不是 Swift Package Manager 本身。
若你需要常駐的自動建置環境,可先參考 遠端 Mac 上的 xcodebuild 自動建置方案,再用真實專案測試解析、普通建置與 Archive。對需要在本地與遠端之間切換的團隊,遠端 Mac 建置環境 可作為環境對照;實際選擇前,仍應先確認私有 Git 認證和執行使用者是否能被穩定保存。
用故障指標快速縮小範圍
| 觀察到的指標 | 優先檢查項目 | 暫時不要做的事 |
|---|---|---|
圖形介面成功,xcodebuild 失敗 |
活動 Xcode、Shell、執行使用者、Git/SSH 設定 | 不要立刻重新產生 Package.resolved |
| 公開套件成功,私有套件失敗 | Git URL、DNS、主機指紋、密鑰與倉庫權限 | 不要把問題歸類為整體快取損壞 |
| 解析顯示成功,但產品不存在 | Package Product、Scheme、Target 與本地套件覆蓋 | 不要繼續測試代理或 DNS |
| 冷快取成功,既有快取失敗 | Repository cache、checkout 目錄與快取內容 | 不要刪除簽名材料 |
| 兩種快取都失敗 | 版本約束、revision、Git 拉取階段 | 不要用一次成功的互動式 Shell 當證據 |
| 解析與普通建置成功,但 Archive 失敗 | 簽名、Provisioning Profile、架構與二進位依賴 | 不要把 Archive 錯誤稱為解析失敗 |
若你目前的方案是共用本地 Mac、臨時雲端工作階段或未固定使用者的自建打包機,常見缺點是快取無法長期保留、私有 Git 認證容易與排程任務脫節,還可能因工作目錄被清理而每次重新拉取。對需要固定 macOS 工具鏈、可保留環境並按週期使用的獨立開發者,租用 MACCOME 的遠端 Mac 會比反覆修補不穩定的臨時環境更容易驗收;但若你需要長期滿載、實體 USB 裝置或必須自行控制硬體,購買本地 Mac 仍可能更合適。先用真實專案完成一次完整驗收,再決定是否把它升級為常駐 iOS 打包伺服器。