新版 CloudKit Console:從 Development 推 Schema 到 Production 的實務筆記
2026 年的 CloudKit Console(Apple 把這個工具從 CloudKit Dashboard 改名叫 CloudKit Console)UI 跟早期的教學文件差異很大——很多部落格說「按左下齒輪」、「右上 Reset」之類的指引已經過時,實際介面上找不到那顆按鈕。
這篇記我這次把 MeowCare 的 schema 從 Development 推到 Production 上 TestFlight 時摸出來的流程。
新版介面結構
進 icloud.developer.apple.com → 選 container(例如 iCloud.rainbow.blooming.MeowCare)→ 左上切 Environment(Development / Production)。
左側 sidebar 分四區:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Monitor
Telemetry
Usage
Logs
Alerts (鎖頭,付費才開)
Data
Records
Zones
Subscriptions
Schema
Indexes ─ Modified
Record Types ─ Modified
Security Roles ─ Modified
History
Settings
Tokens & Keys
Sharing Fallback
左下角有:
Act As iCloud Account…
Deploy Schema Changes…
Import Schema…
以前的「齒輪」/「…」overflow menu 被拆成這些明確的 sidebar 項目跟左下的動作按鈕。
Deploy Schema 到 Production
整個流程:
1. 在 Development 裡確認 schema 已經最新
Schema → Record Types、Indexes、Security Roles 三個分頁,旁邊會標 — Modified(藍字)代表有未 deploy 的變更。如果沒這個標記,代表 Production 已經是最新的。
2. 左下 Deploy Schema Changes…
按下去會彈一個確認視窗,列出要推到 Production 的所有差異:
- 新增的 record type
- 新增的欄位
- 新增的 index
- 新增的 security role
按確認 → 通常 5~30 秒內跑完。
3. Production 環境驗證
頂端切到 Production → 看 Record Types / Indexes / Security Roles 是不是跟 Development 一樣。Modified 標記應該都消失了。
關於 append-only 的硬性限制
CloudKit Production schema 是 append-only:
- ✅ 可以新增 record type / field / index
- ❌ 不能刪除既有 field、改既有 field 型別
- ❌ 不能改 field 名字
這代表開發過程中試錯留下的「死欄位」會永遠在 Production 留痕。例如 MeowCare 之前用 Transformable NSNumber 做數值欄位,跨 iCloud 帳號共享不穩(另外開一篇寫),後來改用原生 Double 重新命名成 xxxDouble,但舊的 xxxRaw(Transformable bytes)欄位在 Production 拿不掉,只能放著。
實務上在 Development 嘗試階段如果把 schema 弄得很髒,越晚 deploy 越好——先在 Development 收斂出乾淨版本再推。如果已經推上去了也無傷大雅,App 不用那些欄位就好。
Reset Environment:看起來有,實際只能一半
新版 Console 的 Reset 按鈕很容易讓人誤會:
Production 的 Reset 按鈕 → Disabled。Apple 不允許清空 Production 環境(Production 可能已經有真實使用者的資料)。
Development 的 Reset 按鈕 → 實際是 Revert from Production。它不會真的清空 Development,而是把 Development 的 schema/data 用 Production 的覆寫回來(在 Dev 裡實驗壞了、想回到乾淨 Production 狀態時用)。
所以如果你的情境是「Development 試壞了、想完全清空重來」,Console 的 Reset 按鈕幫不到你。實際能走的路是:
- 程式碼用
CKModifyRecordZonesOperation呼叫 API 刪 private DB 所有 custom zones - 或在 Console → Data → Zones 頁面手動刪特定 zone(但留著
_defaultZone,系統 zone 不能刪) - 或換 container identifier(最乾淨但要改 entitlements + Apple Developer portal)
Entitlements 跟 Build Configuration 的配合
推上 Production schema 只是一半,app 的 entitlements 也要對:
| Build | 需要的 aps-environment |
|---|---|
| Xcode Debug 跑到裝置 | development |
| Archive → TestFlight / App Store | production |
這個值不會自動翻譯。如果 Debug build 的 entitlement 寫 production,provisioning profile 簽的卻是 development,iOS 會拒絕 APNs 註冊,CloudKit 沒辦法收 silent push 通知、同步會出現延遲(或根本不動)。
標準做法是在 Xcode Target → Build Settings → Code Signing Entitlements 按 Debug / Release 分別指不同的 .entitlements 檔。如果不想搞這麼麻煩,就是每次準備 Archive 前手動把 entitlements 從 development 改回 production,Archive 完再切回來。
順序總結
我這次上 TestFlight 的完整流程:
- 在 Xcode Debug 跑到實機,驗證功能沒問題、Development 環境 sync 正常
- Console → Development → 確認 Schema 是 Modified(要推的變更都 ready)
- 左下
Deploy Schema Changes…→ 確認差異、送出 - 切 Production → 驗證 schema 一致
- 回 Xcode 把
aps-environment改回production - 版本號 bump(
MARKETING_VERSION+CURRENT_PROJECT_VERSION) - Product → Archive → Distribute → TestFlight
- 等 App Store Connect 處理完(10~30 分鐘)
- 在裝置的 TestFlight app 收到新版 → 裝 → 實機驗證
小雷紀錄
- Console Logs 頁面預設只秀 Web UI 自己發的 request(
platform: Other+interfaceType: WEB)。要看真實 iOS app 的 request,filter 要加Database = PRIVATE(或你實際用的 database),把 Web 的雜訊篩掉 - Logs 篩選時間要選對:預設 30 分鐘很容易錯過剛才的操作。我常切 1hr 或 6hr 保險
- Records 頁的 Shared Database 在 owner 帳號下看是空的——shared database 是設計給「被別人分享」的人看的,owner 看自己的資料要去 Private Database
這些在舊版教學裡常常被省略(大家預期 UI 不會變),新版踩到會卡半天。