Skillshub swift-data

SwiftData Best Practices — Modular MVVM-C Data Layer

install
source · Clone the upstream repo
git clone https://github.com/ComeOnOliver/skillshub
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/ComeOnOliver/skillshub "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/pproenca/dot-skills/swift-data" ~/.claude/skills/comeonoliver-skillshub-swift-data && rm -rf "$T"
manifest: skills/pproenca/dot-skills/swift-data/SKILL.md
source content

SwiftData Best Practices — Modular MVVM-C Data Layer

Comprehensive data modeling, persistence, sync architecture, and error handling guide for SwiftData aligned with the clinic modular MVVM-C stack.

Architecture Alignment

This skill enforces the same modular architecture mandated by

swift-ui-architect
:

┌───────────────────────────────────────────────────────────────┐
│ Feature modules: View + ViewModel, no SwiftData imports       │
├───────────────────────────────────────────────────────────────┤
│ Domain: models + repository/coordinator/error protocols        │
├───────────────────────────────────────────────────────────────┤
│ Data: @Model entities, SwiftData stores, repository impls,     │
│ remote clients, retry executor, sync queue, conflict handling  │
└───────────────────────────────────────────────────────────────┘

Key principle: SwiftData types (

@Model
,
ModelContext
,
@Query
,
FetchDescriptor
) live in Data-only implementation code. Feature Views/ViewModels work with Domain types and protocol dependencies.

Clinic Architecture Contract (iOS 26 / Swift 6.2)

All guidance in this skill assumes the clinic modular MVVM-C architecture:

  • Feature modules import
    Domain
    +
    DesignSystem
    only (never
    Data
    , never sibling features)
  • App target is the convergence point and owns
    DependencyContainer
    , concrete coordinators, and Route Shell wiring
  • Domain
    stays pure Swift and defines models plus repository,
    *Coordinating
    ,
    ErrorRouting
    , and
    AppError
    contracts
  • Data
    owns SwiftData/network/sync/retry/background I/O and implements Domain protocols
  • Read/write flow defaults to stale-while-revalidate reads and optimistic queued writes
  • ViewModels call repository protocols directly (no default use-case/interactor layer)

When to Apply

Reference these guidelines when:

  • Defining @Model entity classes and mapping them to domain structs
  • Setting up ModelContainer and ModelContext in the Data layer
  • Implementing repository protocols backed by SwiftData
  • Writing stale-while-revalidate repository reads (
    AsyncStream
    )
  • Implementing optimistic writes plus queued sync operations
  • Configuring entity relationships (one-to-many, inverse)
  • Fetching from APIs and persisting to SwiftData via sync coordinators
  • Handling save failures, corrupt stores, and migration errors
  • Routing AppError traits to centralized error UI infrastructure
  • Building preview infrastructure with sample data
  • Planning schema migrations for app updates

Workflow

Use this workflow when designing or refactoring a SwiftData-backed feature:

  1. Domain design: define domain structs (
    Trip
    ,
    Friend
    ) with validation/computed rules (see
    model-domain-mapping
    ,
    state-business-logic-placement
    )
  2. Entity design: define
    @Model
    entity classes with mapping methods (see
    model-*
    ,
    model-domain-mapping
    )
  3. Repository protocol: define in Domain layer, implement with SwiftData in Data layer (see
    persist-repository-wrapper
    )
  4. Container wiring: configure
    ModelContainer
    once at the app boundary with error recovery (see
    persist-container-setup
    ,
    persist-container-error-recovery
    )
  5. Dependency injection: inject repository protocols via @Environment (see
    state-dependency-injection
    )
  6. ViewModel: create @Observable ViewModel that delegates directly to repository protocols (see
    state-query-vs-viewmodel
    )
  7. CRUD flows: route all insert/delete/update through ViewModel -> Repository (see
    crud-*
    )
  8. Sync architecture: queue writes, execute via sync coordinator with retry policy (see
    sync-*
    )
  9. Relationships: model to-many relationships as arrays; define delete rules (see
    rel-*
    )
  10. Previews: create in-memory containers and sample data for fast iteration (see
    preview-*
    )
  11. Schema evolution: plan migrations with versioned schemas (see
    schema-*
    )

Troubleshooting

  • Data not persisting ->
    persist-model-macro
    ,
    persist-container-setup
    ,
    persist-autosave
    ,
    schema-configuration
  • List not updating after background import ->
    query-background-refresh
    ,
    persist-model-actor
  • List not updating (same-context) ->
    query-property-wrapper
    ,
    state-wrapper-views
  • Duplicates from API sync ->
    schema-unique-attributes
    ,
    sync-conflict-resolution
  • App crashes on launch after model change ->
    schema-migration-recovery
    ,
    persist-container-error-recovery
  • Save failures silently losing data ->
    crud-save-error-handling
  • Stale data from network ->
    sync-offline-first
    ,
    sync-fetch-persist
  • Widget/extension can't see data ->
    persist-app-group
    ,
    schema-configuration
  • Choosing architecture pattern for data views ->
    state-query-vs-viewmodel
    ,
    persist-repository-wrapper

Rule Categories by Priority

PriorityCategoryImpactPrefix
1Data ModelingCRITICAL
model-
2Persistence SetupCRITICAL
persist-
3Querying & FilteringHIGH
query-
4CRUD OperationsHIGH
crud-
5Sync & NetworkingHIGH
sync-
6RelationshipsMEDIUM-HIGH
rel-
7SwiftUI State FlowMEDIUM-HIGH
state-
8Schema & MigrationMEDIUM-HIGH
schema-
9Sample Data & PreviewsMEDIUM
preview-

Quick Reference

1. Data Modeling (CRITICAL)

2. Persistence Setup (CRITICAL)

3. Querying & Filtering (HIGH)

4. CRUD Operations (HIGH)

5. Sync & Networking (HIGH)

6. Relationships (MEDIUM-HIGH)

7. SwiftUI State Flow (MEDIUM-HIGH)

8. Schema & Migration (MEDIUM-HIGH)

9. Sample Data & Previews (MEDIUM)

How to Use

Read individual reference files for detailed explanations and code examples:

Reference Files

FileDescription
references/_sections.mdCategory definitions and ordering
assets/templates/_template.mdTemplate for new rules
metadata.jsonVersion and reference information