1---2name: ios-data-persistence3description: Use when designing iOS persistence, SwiftData migrations, Keychain storage, files, offline sync, or searchable app entities; use ios-architecture for broader module design.4metadata:5 portable: true6 compatible_with:7 - claude-code8 - codex9---1011# iOS Data Persistence12Acknowledgement: Shared by Peter Bamuhigire, techguypeter.com, +256 784 464178.1314<!-- dual-compat-start -->15## Use When1617- Designing, implementing, or reviewing iOS persistence with SwiftData, Core Data migration, UserDefaults, Keychain, file storage, offline sync, Core Spotlight semantic indexing, App Entity exposure, AI local context, or privacy-sensitive caches.18- The task mentions local storage, migrations, offline-first sync, search/indexing, Siri/App Entity data exposure, or AI cache retention.1920## Do Not Use When2122- The task is general iOS implementation with no local data or cache concerns; use `ios-development`.23- The task is only platform capability routing; use `ios-platform-capabilities`.24- The task is security policy rather than persistence mechanics; use `ios-security-and-rbac` alongside this skill.2526## Required Inputs2728- Data model, sensitivity classification, deployment target, sync/backend contract, offline requirements, account/tenant model, deletion rules, and whether data is exposed to Spotlight, Siri, widgets, or AI context.2930## Workflow31321. Load `ios-development` for Swift and project standards.332. Choose storage: UserDefaults, Keychain, SwiftData/Core Data, FileManager, URLCache/NSCache, Core Spotlight, or an AI local-context cache.343. Load `references/ios-swiftdata.md` for SwiftData details.354. Load `references/semantic-indexing-and-ai-caches-wwdc26.md` when data is exposed to Siri, Spotlight, App Entities, widgets, or AI.365. Produce a model spec, migration plan, cache policy, deletion policy, and test plan.3738## Quality Standards3940- Persistence models must separate stored data, domain entities, DTOs, and search/intent projections when privacy or API shape differs.41- Secrets belong in Keychain or stronger platform storage, not UserDefaults, SwiftData, Spotlight, or logs.42- Offline data must have conflict, sync, stale-state, and deletion behavior.43- Indexed or AI-context data must have retention, invalidation, and user/account cleanup rules.4445## Anti-Patterns4647- Exposing stored models directly as App Entities without reviewing fields.48- Keeping stale Spotlight entries after logout, role change, tenant switch, or deletion.49- Using local AI context as a hidden long-term memory without retention and deletion controls.50- Treating SwiftData migrations as a compile-time concern only.5152## Outputs5354- Persistence model spec, storage decision, SwiftData migration plan, offline sync plan, search/index projection, AI cache policy, or review findings.5556## Evidence Produced5758| Category | Artifact | Format | Example |59|----------|----------|--------|---------|60| Data safety | Persistence model spec | Markdown doc per `skill-composition-standards/references/entity-model-template.md` covering entities, projections, retention, and deletion | `docs/ios/persistence-model-orders.md` |61| Correctness | Persistence test plan | Markdown doc listing CRUD, migration, sync, index, and deletion test cases | `docs/ios/persistence-tests-orders.md` |6263## References6465- `references/ios-swiftdata.md` for SwiftData `@Model`, relationships, model actors, migrations, CloudKit, and testing.66- `references/semantic-indexing-and-ai-caches-wwdc26.md` for Core Spotlight, App Entities, Siri semantic index privacy, local AI context, and cache invalidation rules.67- `references/skill-deep-dive.md` for UserDefaults, Keychain, repository pattern, file storage, URLCache/NSCache, offline-first architecture, and cross-skill references.68<!-- dual-compat-end -->6970## Storage Decision Guide7172## Inputs7374| Artefact | Produced by | Required? | Why |75|---|---|---|---|76| Entity and retention model | Product and backend owners | required | Defines durable records and deletion duties |77| API conflict contract | `api-design-first` | conditional | Governs offline reconciliation |78| Data classification | `ios-security-and-rbac` | required | Selects Keychain, file protection, or database storage |7980## Decision Rules8182| Data | Storage |83|---|---|84| Credential or private key | Keychain or Secure Enclave reference |85| Queryable application records | SwiftData with an explicit migration plan |86| Large media or export | Protected file with metadata in SwiftData |87| Financial offline conflict | Server-authoritative merge with idempotency |8889## Degraded Mode9091Without a runnable schema, provide the model delta, migration stages, backup/rollback path, and fixtures required for validation. Do not assert migration safety without testing old stores.92If execution is unavailable, report migration safety as unverified.9394## Domain Anti-Patterns9596- Storing tokens in UserDefaults. Fix: use an access-group-scoped Keychain item.97- Changing a persistent model without old-store fixtures. Fix: test each supported migration path.98- Caching private AI input indefinitely. Fix: define purpose-bound retention and deletion.99- Treating Spotlight as authoritative storage. Fix: rebuild the index from the source database.100- Resolving ledger conflicts by last-write-wins. Fix: reconcile against server versions.101102| Data Type | Storage | Example |103|---|---|---|104| User preferences | UserDefaults | Theme, language, sort order |105| Tokens / credentials | Keychain Services | JWT tokens, API keys, passwords |106| Structured app data | SwiftData or Core Data | Products, orders, customers |107| Searchable safe projections | Core Spotlight / App Entity projection | Title, display date, safe summary |108| Large files / images | FileManager | Photos, PDFs, exports |109| Temporary cache | URLCache / NSCache | API response caching |110| AI local context | App-owned encrypted cache or SwiftData projection | Prompt-safe summaries, never raw secrets |111112Rule of thumb: simple flag/scalar = UserDefaults. Secret = Keychain. Relationships/querying = SwiftData. Binary blob = FileManager. Search/Siri/AI exposure = separate projection with explicit privacy review.