Sign in with Apple 的原生 iOS 流程使用 ASAuthorizationController,不需要設定網頁登入用的 Return URL,基本串接通常只要幾十行程式碼。但實機測試時如果跳出「註冊未完成」(英文版是 Sign Up Not Completed),排查會突然變得很棘手:訊息出現在 Apple 的系統授權介面裡,不是我們的 App 畫面,而且 App 端不一定拿得到有用的錯誤。這篇文章記錄一次從症狀到根因的完整排查,包含怎麼從實機撈系統 log,以及 AKSQLError -6003 出現時該怎麼處理。
為什麼這個錯誤特別難查
一般的登入錯誤會沿著程式碼流回來,在 onCompletion 或 delegate 裡拿得到 ASAuthorizationError,至少知道授權是被取消、失敗還是沒有被處理。「註冊未完成」不一樣,它發生在系統授權 sheet 與 Apple 伺服器溝通的階段。這次案例中,畫面停在錯誤訊息時 completion handler 沒有被呼叫;其他版本或第三方套件也可能只收到 .canceled(1001)或 .unknown(1000),仍看不出真正原因。
這代表只在 App 端加 log,通常查不到系統授權流程裡的失敗原因。entitlement 與 provisioning profile 還是要檢查,但不能只看 Xcode 畫面就認定設定正確,也不能在沒有證據的情況下反覆重建 profile。
排查時先檢查 entitlement、provisioning profile、App ID 與帳號狀態,再從系統 log 找 Apple 伺服器回傳的錯誤。

可以客觀驗證的四個環節
以下四項都有指令、介面或交叉測試可以檢查。
entitlement 是否簽入 App
project.yml 或 Xcode 介面上有設定,不代表 entitlement 已簽入建置產物。可以直接檢查 .app:
# 看實際簽進 App 的 entitlements
codesign --display --entitlements - --xml MyApp.app \
| plutil -convert xml1 -o - -
# 應該要看到這一段
# "com.apple.developer.applesignin" => [ "Default" ]
# "application-identifier" => "TEAMID.com.example.myapp"
provisioning profile 允不允許這個 entitlement
App 簽了 entitlement,但 profile 沒有授權,簽署或安裝階段就可能失敗。Apple 的 TN3125 把 profile 內的 entitlements 稱為 allowlist;App 實際宣告的 entitlement 與 profile 允許的項目是兩件事,因此要分開確認:
# profile 包在 .app 裡,先解成 plist
security cms -D -i MyApp.app/embedded.mobileprovision \
-o /tmp/myapp-profile.plist
# 只讀 Sign in with Apple 對應的 entitlement
/usr/libexec/PlistBuddy \
-c 'Print :Entitlements:com.apple.developer.applesignin' \
/tmp/myapp-profile.plist
# 正常會看到 Array 與 Default
Xcode 16 把下載的 profile 存放位置從 ~/Library/MobileDevice/Provisioning Profiles/ 搬到 ~/Library/Developer/Xcode/UserData/Provisioning Profiles/,同時仍會載入舊路徑已有的 profile。舊路徑找不到檔案不代表 Xcode 沒有 profile;直接檢查建置產物裡的 embedded.mobileprovision 比較準確。
App ID 在 Apple 那端的設定
Developer Portal 的網頁看得到這項設定,App Store Connect API 也可以直接查,適合寫進檢查腳本。這次檢查的是未分組、作為 primary App ID 的識別碼,因此 APPLE_ID_AUTH capability 必須存在,設定也應為 PRIMARY_APP_CONSENT(介面上的 Enable as a primary App ID)。如果 App ID 已經跟另一個 primary App ID 分組,則要檢查它指向的 primary App ID 是否正確:
# 需要先用 ASC API Key 簽一顆 JWT 當 Bearer token
# -g 會關閉 curl 的中括號 URL 展開,否則 filter[identifier] 可能被誤判
curl -g -s -H "Authorization: Bearer $JWT" \
"https://api.appstoreconnect.apple.com/v1/bundleIds?filter[identifier]=com.example.myapp&include=bundleIdCapabilities"
# 回應裡應該找得到
# "capabilityType": "APPLE_ID_AUTH"
# "settings": [{"key":"APPLE_ID_AUTH_APP_CONSENT","options":[{"key":"PRIMARY_APP_CONSENT"}]}]
App ID 設定畫面裡的 Server-to-Server Notification Endpoint 是選填項目,留空不會阻止原生登入。Domains and Subdomains 與 Return URLs 則設在 Services ID,提供網站或其他平台的網頁驗證流程使用。原生 iOS App 直接透過 ASAuthorizationController 授權,沒有使用 Services ID 的話,不需要為了這個錯誤補 Return URL。
Apple 帳號本身的狀態
Sign in with Apple 要求該 Apple 帳號啟用雙重認證。另外,裝置上「設定 → 帳號名稱 → 使用 Apple 帳號登入」會列出授權過的 App。目標 App 已經出現在清單裡,而且問題只發生在重新建立帳號時,可以先停止使用 Sign in with Apple,再重新授權;不在清單裡就不用做這一步。
比較有效的交叉測試,是拿同一個 Apple 帳號、同一台裝置與同一個網路,到其他開發者的 App 完成一次首次授權。能成功的話,可以大致排除帳號、裝置與網路,但不能因此斷定 Apple 的 Sign in with Apple 服務整體正常,因為異常仍可能只影響特定 Team ID 或 Client ID。
從實機撈系統 log
四項檢查都正常卻仍然失敗時,需要讀取系統 log。負責 Sign in with Apple 的系統程序叫 akd(AuthKit daemon),它會把失敗原因寫進系統 log,只是那些訊息不會經過我們的 App。
macOS 的 log stream 沒有讀取配對 iPhone 的 --device 選項。要從真機取回一段時間的 Unified Log,可以用 log collect --device 建立 .logarchive:
# 先在手機上重現一次失敗,再立刻收集最近 10 分鐘的 log
sudo /usr/bin/log collect --device --last 10m --output phone.logarchive
# 收完用 predicate 過濾,只看 AuthKit 相關的 error 與 fault
/usr/bin/log show --archive phone.logarchive --style compact --info --debug \
--predicate '(process == "akd" OR process == "AuthKitUIService") AND (messageType == error OR messageType == fault)'
兩個地方容易卡住。第一,zsh 有同名的 log 內建指令,直接打 log collect 可能得到 too many arguments,因此範例固定寫完整路徑 /usr/bin/log。第二,從配對裝置收集時若遇到權限錯誤,再確認指令前面有 sudo。手機也要先信任這台 Mac,並保持連線。
AKSQLError -6003 與 Client ID 查詢失敗
過濾出來的錯誤鏈大致是這樣(時間戳與執行緒編號已省略):
E akd [authkit:siwa] Encountered error while fetching developer team:
Error Domain=AKSQLError Code=-6003
E akd [authkit:siwa] Cannot perform password request without password request.
E AuthKitUIService [LocalAuthentication] Code=-1008
"Can't retry event, because no suitable mechanism is running."
E akd [authkit:core] Invalid/missing value for key acname: (null)
E akd [authkit:core] SRP authentication with server failed!
Error Domain=com.apple.AppleIDAuthSupport Code=2
E akd [authkit:siwa] Error performing auth request:
Error Domain=AKAuthenticationError Code=-7003
這串訊息很容易讀錯。中間那幾行看起來像是身分驗證出了問題,SRP authentication with server failed 指向密碼驗證流程,LocalAuthentication 則寫著沒有合適的驗證機制。如果從這裡開始查,很容易把方向放在 Apple 帳號、Face ID 或裝置憑證,接著反覆登入 iCloud、重開機與重設密碼。
這次案例要先看第一行:fetching developer team 失敗,錯誤碼是 AKSQLError -6003。完整訊息還帶著 No applications were found with the provided Client ID,代表 Apple 伺服器用這個 Client ID 查不到可用的 App 紀錄。原生流程裡的 Client ID 就是 bundle ID,因此問題範圍已經縮小到 App ID、Team ID 與 Apple 伺服器上的對應狀態。
取不到 team 之後,後面的流程才接著冒出 acname: (null)、SRP 握手失敗與 AKAuthenticationError -7003。把同一帳號在其他 App 的首次授權成功結果放在一起看,這幾行比較像上游 Client ID 查詢失敗後的連鎖錯誤,不應只看 bad password 就要求測試帳號重設密碼。
注意:AKSQLError 與 AKAuthenticationError 都是系統內部錯誤,Apple 沒有公開穩定的錯誤碼對照表。診斷時要同時保留完整訊息、發生時間與交叉測試結果,不能把 -6003 單獨當成永遠不變的公開 API 規格。
這次有效的修法:重設 capability
完成前面的檢查,而且 log 明確出現 Client ID 查詢失敗後,這次案例到 Developer Portal 的 Identifiers 找到該 App ID,重設 Sign in with Apple capability:
- 取消勾選 Sign in with Apple,按 Save
- 重新勾選,Configure 選 Enable as a primary App ID,再按 Save
Apple 文件有提醒,關閉 Sign in with Apple capability 會重設已儲存的設定。這次案例重新開啟後,第一次嘗試就成功,App 端一行程式碼都沒有改;合理推論是重新儲存讓伺服器端的 App ID 對應恢復正常。不過 Apple 沒有把「關掉再開」列為 -6003 的正式修復流程,也有開發者回報重設後仍失敗。
注意:App ID 已經群組其他 App 或關聯 Services ID 的話,先記下 primary App ID、分組與網站設定。關閉 capability 會重設設定,不適合在正式服務上沒有盤點就直接操作。
這次本機的 provisioning profile 不需要重新產生,因為原本 profile 與簽進 App 的 entitlement 都正確。其他專案若在重設 capability 後看到 Xcode 更新 signing assets,仍要重新檢查新建置產物,不能把這次結果當成所有專案都不用更新 profile。
等待、重設與回報的判斷
「註冊未完成」不是單一錯誤碼的固定翻譯,-7003 也不能直接等同 -6003。實務上可以依照設定時間、影響範圍與 log 分成三條路徑。
如果是剛剛才啟用或修改 Sign in with Apple,可以先保留設定並隔一段時間重測,避免在傳播期間連續改動。開發者論壇有人回報一至兩天後恢復,但 Apple 沒有公布「最長 48 小時」的服務保證。2025 年 6 月的服務事件甚至持續五天,Apple 後來確認部分新建或剛修改的 App ID、Services ID 設定受到影響,原生框架會直接顯示「註冊未完成」。
如果是從第一天就沒有成功過,而且不同 Apple 帳號、裝置與網路都失敗,先完成 entitlement、profile、App ID 與帳號四項檢查,再讀 akd log。後端沒有任何成功登入紀錄只能證明這條路徑尚未成功,不能單靠這點判定一定是 Apple 伺服器故障。
手上若有同一團隊較早建立、已知可用的 App ID,可以用相同的官方範例做交叉測試。舊 App ID 正常、新 App ID 失敗,比「換一份實作再試」更能分辨問題是否跟剛建立的識別碼有關。個人與組織帳號都曾有相同回報,因此帳號類型不是可靠的判斷條件。
重設 capability 仍無效,或正式服務不適合重設時,Apple DTS 的建議是安裝 Accounts/AuthKit logging profile,重現問題後立即收集 sysdiagnose,再用 Feedback Assistant 回報。內容至少要有 Team ID、Bundle ID/Client ID、受影響的 Apple 帳號、重現時間與 sysdiagnose;螢幕錄影可以一併附上。簡單的 .logarchive 適合自己定位方向,提交 Apple 時仍以 DTS 要求的 sysdiagnose 為準。
這次排查留下的幾個判斷原則
這次排查可以整理成三個判斷原則,重點都在排查順序。
錯誤鏈要從最上游讀起。錯誤鏈最後顯示的錯誤,可能只是前面環節失敗後的連鎖反應。這次如果只從 SRP authentication failed 開始查,方向會落在帳號密碼;往前看到 Client ID 查詢失敗,再配合其他 App 可正常授權的結果,才有足夠證據改查 App ID 與伺服器端狀態。
先確認診斷資料在哪一層。App 拿不到有用的錯誤,不代表系統沒有留下資訊。系統授權流程要讀 Unified Log;Apple 那端的 capability 可以用 App Store Connect API 查,而且適合寫成可重複執行的檢查。
沒有證據之前不要交付新版本。原因可能在 Apple 後端時,反覆重裝或修改程式碼通常無法提供新證據,應先收集系統 log。
參考來源
- Apple:Configuring Sign in with Apple support
- Apple:About Sign in with Apple
- Apple:Group apps for Sign in with Apple
- Apple TN3125:Inside Code Signing: Provisioning Profiles
- Apple:Xcode 16 Release Notes
- Apple:App Store Connect API Bundle ID Capabilities
- Apple TN3159:Sign in with Apple 的 native client identifier
- Apple Developer Forums:Sign Up Not Completed
- Apple Developer Forums:Sign in with Apple fails with ASAuthorizationError.canceled
- Apple DTS:2025 年 6 月 Sign in with Apple 服務事件
- Apple DTS:Gathering required information for troubleshooting Sign in with Apple
- Apple Support:Manage your apps with Sign in with Apple