症狀 → 最快解法: 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 設定。若兩者都失敗,才優先檢查版本圖、套件網址與存取權限。保留修復前後兩份日誌,否則你無法判斷某次清理究竟改變了什麼。

先分清楚四種狀態

「解析失敗」不等於所有套件問題。你要把狀態拆開:

  1. 依賴解析:版本約束是否能找到一組可行解。
  2. 原始碼檢出:Git 是否能連線、驗證並下載指定版本。
  3. 依賴圖與產品生成:套件是否產生預期的產品與 target。
  4. 連結 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 或整體網路問題。只有私有套件失敗時,依序驗證:

  1. Git URL 是否與 Package.swift 或專案記錄完全一致。
  2. DNS、代理與防火牆是否允許連線到 <GIT_HOST>
  3. SSH 主機指紋是否已被執行使用者信任。
  4. SSH Key 是否在該工作階段載入。
  5. 該帳號是否有讀取倉庫與指定 revision 的權限。
  6. 失敗是在建立連線、完成認證,還是拉取物件時發生。

不要在指令列中直接放入真實密碼或 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 命令,連續驗證三個階段:

  1. 依賴解析完成,且日誌中的套件版本與鎖定檔一致。
  2. 一般建置完成,沒有把解析問題誤判成編譯問題。
  3. 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 打包伺服器。