83 lines
3.8 KiB
Markdown
83 lines
3.8 KiB
Markdown
# SwiftData to CloudKit Sync Requirements (Reusable)
|
|
|
|
Primary source of truth lives in Bedrock:
|
|
`/Users/mattbruce/Documents/Projects/iPhone/Andromida/Bedrock/Sources/Bedrock/Storage/SWIFTDATA_CLOUDKIT_SETUP_GUIDE.md`
|
|
|
|
This Andromida copy is app-facing reference material and should stay aligned with the Bedrock guide.
|
|
|
|
Use this checklist for any iOS app that uses SwiftData with CloudKit and requires near-real-time multi-device sync.
|
|
|
|
## 1) Capabilities and Entitlements
|
|
|
|
- Enable `iCloud` with `CloudKit` for the app target.
|
|
- Enable `Push Notifications` for the app target.
|
|
- Enable `Background Modes > Remote notifications`.
|
|
- Add App Group if app + widget share local SQLite.
|
|
|
|
Required entitlement keys:
|
|
- `com.apple.developer.icloud-container-identifiers`
|
|
- `com.apple.developer.icloud-services` including `CloudKit`
|
|
- `com.apple.developer.ubiquity-kvstore-identifier` (if KVS is used)
|
|
- `aps-environment` (must resolve per config)
|
|
- `com.apple.security.application-groups` (if widget/app group storage is used)
|
|
|
|
## 2) Build Configuration
|
|
|
|
Use xcconfig variables so environments are explicit and portable:
|
|
|
|
- Debug: `APS_ENVIRONMENT = development`
|
|
- Release: `APS_ENVIRONMENT = production`
|
|
|
|
Entitlements should reference variables, not hard-coded values, where possible.
|
|
|
|
## 3) Model and Schema Constraints (SwiftData + CloudKit)
|
|
|
|
- Avoid `@Attribute(.unique)` in CloudKit-mirrored models.
|
|
- Ensure all stored properties have defaults or are optional.
|
|
- Keep relationships optional for CloudKit compatibility.
|
|
- Use additive schema evolution only (add fields/models; do not remove/rename/change types in place).
|
|
|
|
## 4) Runtime Sync Behavior
|
|
|
|
- Prefer Bedrock `SwiftDataCloudKitSyncManager` as the reusable remote observer/lifecycle component.
|
|
- Observe `.NSPersistentStoreRemoteChange` to detect remote merges.
|
|
- On remote change, refetch from SwiftData and invalidate derived caches.
|
|
- For long-lived stores, recreate `ModelContext` on remote change before refetch when stale objects are observed.
|
|
- Keep a foreground fallback refresh as a safety net, but do not rely on force-quit/relaunch behavior.
|
|
- Emit structured logs for remote sync events (event count + timestamp) for debugging.
|
|
|
|
## 5) UI Freshness Requirements
|
|
|
|
- UI must re-render on each remote merge, even for batched updates.
|
|
- Keep an observable refresh version/counter and increment on each successful reload.
|
|
- Ensure list/detail views do not rely on stale assumptions when models are updated remotely.
|
|
- Make high-frequency interaction rows fully tappable to reduce missed user actions.
|
|
|
|
## 6) Verification Matrix
|
|
|
|
Test all cases on two physical devices with the same Apple ID and same app flavor:
|
|
|
|
1. Single toggle on Device A appears on Device B while both apps are open.
|
|
2. Rapid batch toggles on Device A all appear on Device B without manual pull-to-refresh.
|
|
3. Device B in background receives updates after foregrounding (without force quit).
|
|
4. Airplane mode recovery syncs correctly after reconnection.
|
|
5. Simultaneous edits resolve predictably (CloudKit last-writer-wins).
|
|
|
|
## 7) Observability and Console Checks
|
|
|
|
- Device logs: filter by sync logger category (for example `CloudKitSync`).
|
|
- CloudKit Console: validate record updates in the app container private database.
|
|
- If pushes are delivered but UI is stale, investigate context freshness and view invalidation, not transport.
|
|
|
|
## 8) Reuse Checklist for New Apps
|
|
|
|
Before shipping any new SwiftData+CloudKit app:
|
|
|
|
- [ ] Capabilities: iCloud/CloudKit + Push + Remote Notifications are enabled
|
|
- [ ] Entitlements include `aps-environment` and correct container IDs
|
|
- [ ] xcconfig defines `APS_ENVIRONMENT` per configuration
|
|
- [ ] Remote change observer reloads data and invalidates caches
|
|
- [ ] UI has deterministic invalidation on remote reload
|
|
- [ ] Two-device batch-update test passes without manual refresh
|
|
- [ ] CloudKit Console verification documented in README/PRD
|