swift-data

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

SwiftData Best Practices — Modular MVVM-C Data Layer

SwiftData最佳实践 — 模块化MVVM-C数据层

Comprehensive data modeling, persistence, sync architecture, and error handling guide for SwiftData aligned with the clinic modular MVVM-C stack.
本指南为SwiftData提供了全面的数据建模、持久化、同步架构及错误处理方案,与诊所式模块化MVVM-C技术栈保持一致。

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.
本技能遵循
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  │
└───────────────────────────────────────────────────────────────┘
核心原则: SwiftData类型(
@Model
ModelContext
@Query
FetchDescriptor
)仅存在于数据层实现代码中。功能模块的View/ViewModel仅与领域层类型和协议依赖交互。

Clinic Architecture Contract (iOS 26 / Swift 6.2)

诊所架构规范(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)
本技能中的所有指导均基于诊所式模块化MVVM-C架构:
  • 功能模块仅导入
    Domain
    +
    DesignSystem
    (绝不导入
    Data
    ,也不导入同级功能模块)
  • App目标作为聚合点,负责
    DependencyContainer
    、具体协调器及路由壳的配置
  • Domain
    层为纯Swift代码,定义模型及仓库、
    *Coordinating
    ErrorRouting
    AppError
    协议
  • Data
    层负责SwiftData/网络/同步/重试/后台I/O,并实现领域层协议
  • 默认采用缓存优先读取和乐观队列写入的读写流程
  • ViewModel直接调用仓库协议(默认不使用用例/交互器层)

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
在以下场景中参考本指南:
  • 定义@Model实体类并将其映射到领域结构体
  • 在数据层配置ModelContainer和ModelContext
  • 实现基于SwiftData的仓库协议
  • 编写缓存优先的仓库读取逻辑(
    AsyncStream
  • 实现乐观写入及队列同步操作
  • 配置实体关系(一对多、反向关联)
  • 通过同步协调器从API获取数据并持久化到SwiftData
  • 处理保存失败、存储损坏及迁移错误
  • 将AppError特征路由到集中式错误UI基础设施
  • 使用示例数据构建预览基础设施
  • 为应用更新规划 Schema 迁移

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-*
    )
在设计或重构基于SwiftData的功能时,遵循以下流程:
  1. 领域设计:定义领域结构体(如
    Trip
    Friend
    )并添加验证/计算规则(参考
    model-domain-mapping
    state-business-logic-placement
  2. 实体设计:定义
    @Model
    实体类并添加映射方法(参考
    model-*
    model-domain-mapping
  3. 仓库协议:在领域层定义协议,在数据层基于SwiftData实现(参考
    persist-repository-wrapper
  4. 容器配置:在应用边界一次性配置
    ModelContainer
    并添加错误恢复逻辑(参考
    persist-container-setup
    persist-container-error-recovery
  5. 依赖注入:通过@Environment注入仓库协议(参考
    state-dependency-injection
  6. ViewModel:创建@Observable ViewModel,直接委托给仓库协议(参考
    state-query-vs-viewmodel
  7. CRUD流程:所有增删改操作通过ViewModel -> Repository路由(参考
    crud-*
  8. 同步架构:将写入操作加入队列,通过同步协调器结合重试策略执行(参考
    sync-*
  9. 关系配置:将一对多关系建模为数组;定义删除规则(参考
    rel-*
  10. 预览设置:创建内存容器和示例数据以加速迭代(参考
    preview-*
  11. Schema演进:使用版本化Schema规划迁移(参考
    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
  • 数据未持久化 ->
    persist-model-macro
    persist-container-setup
    persist-autosave
    schema-configuration
  • 后台导入后列表未更新 ->
    query-background-refresh
    persist-model-actor
  • 同一上下文下列表未更新 ->
    query-property-wrapper
    state-wrapper-views
  • API同步导致重复数据 ->
    schema-unique-attributes
    sync-conflict-resolution
  • 模型变更后应用启动崩溃 ->
    schema-migration-recovery
    persist-container-error-recovery
  • 保存失败导致数据静默丢失 ->
    crud-save-error-handling
  • 网络数据过期 ->
    sync-offline-first
    sync-fetch-persist
  • Widget/扩展无法读取数据 ->
    persist-app-group
    schema-configuration
  • 为数据视图选择架构模式 ->
    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-
优先级类别影响等级前缀
1数据建模关键
model-
2持久化设置关键
persist-
3查询与过滤
query-
4CRUD操作
crud-
5同步与网络
sync-
6关系配置中高
rel-
7SwiftUI状态流中高
state-
8Schema与迁移中高
schema-
9示例数据与预览
preview-

Quick Reference

快速参考

1. Data Modeling (CRITICAL)

1. 数据建模(关键)

  • model-domain-mapping
    - Map @Model entities to domain structs across Domain/Data boundaries
  • model-custom-types
    - Use custom types over parallel arrays
  • model-class-for-persistence
    - Use classes for SwiftData entity types
  • model-identifiable
    - Conform entities to Identifiable with UUID
  • model-initializer
    - Provide custom initializers for entity classes
  • model-computed-properties
    - Use computed properties for derived data
  • model-defaults
    - Provide sensible default values for entity properties
  • model-transient
    - Mark non-persistent properties with @Transient
  • model-external-storage
    - Use external storage for large binary data
  • model-domain-mapping
    - 在领域/数据层边界将@Model实体映射到领域结构体
  • model-custom-types
    - 使用自定义类型而非并行数组
  • model-class-for-persistence
    - 为SwiftData实体类型使用类
  • model-identifiable
    - 使实体遵循Identifiable协议并使用UUID
  • model-initializer
    - 为实体类提供自定义初始化方法
  • model-computed-properties
    - 使用计算属性处理派生数据
  • model-defaults
    - 为实体属性提供合理的默认值
  • model-transient
    - 使用@Transient标记非持久化属性
  • model-external-storage
    - 为大型二进制数据使用外部存储

2. Persistence Setup (CRITICAL)

2. 持久化设置(关键)

  • persist-repository-wrapper
    - Wrap SwiftData behind Domain repository protocols
  • persist-model-macro
    - Apply @Model macro to all persistent types
  • persist-container-setup
    - Configure ModelContainer at the App level
  • persist-container-error-recovery
    - Handle ModelContainer creation failure with store recovery
  • persist-context-environment
    - Access ModelContext via @Environment (Data layer)
  • persist-autosave
    - Enable autosave for manually created contexts
  • persist-enumerate-batch
    - Use ModelContext.enumerate for large traversals
  • persist-in-memory-config
    - Use in-memory configuration for tests and previews
  • persist-app-group
    - Use App Groups for shared data storage
  • persist-model-actor
    - Use @ModelActor for background SwiftData work
  • persist-identifier-transfer
    - Pass PersistentIdentifier across actors
  • persist-repository-wrapper
    - 将SwiftData封装在领域仓库协议之后
  • persist-model-macro
    - 为所有持久化类型应用@Model宏
  • persist-container-setup
    - 在App层面配置ModelContainer
  • persist-container-error-recovery
    - 通过存储恢复处理ModelContainer创建失败
  • persist-context-environment
    - 在数据层通过@Environment访问ModelContext
  • persist-autosave
    - 为手动创建的上下文启用自动保存
  • persist-enumerate-batch
    - 使用ModelContext.enumerate处理大型遍历
  • persist-in-memory-config
    - 为测试和预览使用内存配置
  • persist-app-group
    - 使用App Groups实现数据共享存储
  • persist-model-actor
    - 使用@ModelActor处理后台SwiftData任务
  • persist-identifier-transfer
    - 在Actor之间传递PersistentIdentifier

3. Querying & Filtering (HIGH)

3. 查询与过滤(高)

  • query-property-wrapper
    - Use @Query for declarative data fetching (Data layer)
  • query-background-refresh
    - Force view refresh after background context inserts
  • query-sort-descriptors
    - Apply sort descriptors to @Query
  • query-predicates
    - Use #Predicate for type-safe filtering
  • query-dynamic-init
    - Use custom view initializers for dynamic queries
  • query-fetch-descriptor
    - Use FetchDescriptor outside SwiftUI views
  • query-fetch-tuning
    - Tune FetchDescriptor paging and pending-change behavior
  • query-localized-search
    - Use localizedStandardContains for search
  • query-expression
    - Use #Expression for reusable predicate components (iOS 18+)
  • query-property-wrapper
    - 在数据层使用@Query进行声明式数据获取
  • query-background-refresh
    - 后台上下文插入后强制刷新视图
  • query-sort-descriptors
    - 为@Query应用排序描述符
  • query-predicates
    - 使用#Predicate进行类型安全过滤
  • query-dynamic-init
    - 为动态查询使用自定义视图初始化方法
  • query-fetch-descriptor
    - 在SwiftUI视图外使用FetchDescriptor
  • query-fetch-tuning
    - 调整FetchDescriptor的分页和待处理变更行为
  • query-localized-search
    - 使用localizedStandardContains实现搜索
  • query-expression
    - 使用#Expression实现可复用的谓词组件(iOS 18+)

4. CRUD Operations (HIGH)

4. CRUD操作(高)

  • crud-insert-context
    - Insert models via repository implementations
  • crud-delete-indexset
    - Delete via repository with IndexSet from onDelete
  • crud-sheet-creation
    - Use sheets for focused data creation via ViewModel
  • crud-cancel-delete
    - Avoid orphaned records by persisting only on save
  • crud-undo-cancel
    - Enable undo and use it to cancel edits
  • crud-edit-button
    - Provide EditButton for list management
  • crud-dismiss-save
    - Dismiss modal after ViewModel save completes
  • crud-save-error-handling
    - Handle repository save failures with user feedback
  • crud-insert-context
    - 通过仓库实现插入模型
  • crud-delete-indexset
    - 通过仓库处理onDelete的IndexSet删除操作
  • crud-sheet-creation
    - 使用Sheet结合ViewModel实现聚焦式数据创建
  • crud-cancel-delete
    - 仅在保存时持久化数据,避免孤立记录
  • crud-undo-cancel
    - 启用撤销功能并用于取消编辑
  • crud-edit-button
    - 提供EditButton用于列表管理
  • crud-dismiss-save
    - ViewModel保存完成后关闭模态框
  • crud-save-error-handling
    - 处理仓库保存失败并向用户反馈

5. Sync & Networking (HIGH)

5. 同步与网络(高)

  • sync-fetch-persist
    - Use injected sync services to fetch and persist API data
  • sync-offline-first
    - Design offline-first architecture with repository reads and background sync
  • sync-conflict-resolution
    - Implement conflict resolution for bidirectional sync
  • sync-fetch-persist
    - 使用注入的同步服务获取并持久化API数据
  • sync-offline-first
    - 设计离线优先架构,结合仓库读取和后台同步
  • sync-conflict-resolution
    - 实现双向同步的冲突解决逻辑

6. Relationships (MEDIUM-HIGH)

6. 关系配置(中高)

  • rel-optional-single
    - Use optionals for optional relationships
  • rel-array-many
    - Use arrays for one-to-many relationships
  • rel-inverse-auto
    - Rely on SwiftData automatic inverse maintenance
  • rel-delete-rules
    - Configure cascade delete rules for owned relationships
  • rel-explicit-sort
    - Sort relationship arrays explicitly
  • rel-optional-single
    - 为可选关系使用可选类型
  • rel-array-many
    - 为一对多关系使用数组
  • rel-inverse-auto
    - 依赖SwiftData自动维护反向关联
  • rel-delete-rules
    - 为所属关系配置级联删除规则
  • rel-explicit-sort
    - 显式排序关系数组

7. SwiftUI State Flow (MEDIUM-HIGH)

7. SwiftUI状态流(中高)

  • state-query-vs-viewmodel
    - Route all data access through @Observable ViewModels
  • state-business-logic-placement
    - Place business logic in domain value types and repository-backed ViewModels
  • state-dependency-injection
    - Inject repository protocols via @Environment
  • state-bindable
    - Use @Bindable for two-way model binding
  • state-local-state
    - Use @State for view-local transient data
  • state-wrapper-views
    - Extract wrapper views for dynamic query state
  • state-query-vs-viewmodel
    - 所有数据访问均通过@Observable ViewModel路由
  • state-business-logic-placement
    - 将业务逻辑放置在领域值类型和仓库驱动的ViewModel中
  • state-dependency-injection
    - 通过@Environment注入仓库协议
  • state-bindable
    - 使用@Bindable实现双向模型绑定
  • state-local-state
    - 使用@State存储视图本地临时数据
  • state-wrapper-views
    - 提取包装视图处理动态查询状态

8. Schema & Migration (MEDIUM-HIGH)

8. Schema与迁移(中高)

  • schema-define-all-types
    - Define schema with all model types
  • schema-unique-attributes
    - Use @Attribute(.unique) for natural keys
  • schema-unique-macro
    - Use #Unique for compound uniqueness (iOS 18+)
  • schema-index
    - Use #Index for hot predicates and sorts (iOS 18+)
  • schema-migration-plan
    - Plan migrations before changing models
  • schema-migration-recovery
    - Plan migration recovery for schema changes
  • schema-configuration
    - Customize storage with ModelConfiguration
  • schema-define-all-types
    - 使用所有模型类型定义Schema
  • schema-unique-attributes
    - 为自然键使用@Attribute(.unique)
  • schema-unique-macro
    - 使用#Unique实现复合唯一性(iOS 18+)
  • schema-index
    - 为高频谓词和排序使用#Index(iOS 18+)
  • schema-migration-plan
    - 在修改模型前规划迁移方案
  • schema-migration-recovery
    - 为Schema变更规划迁移恢复策略
  • schema-configuration
    - 使用ModelConfiguration自定义存储

9. Sample Data & Previews (MEDIUM)

9. 示例数据与预览(中)

  • preview-sample-singleton
    - Create a SampleData singleton for previews
  • preview-in-memory
    - Use in-memory containers for preview isolation
  • preview-static-data
    - Define static sample data on model types
  • preview-main-actor
    - Annotate SampleData with @MainActor
  • preview-sample-singleton
    - 创建SampleData单例用于预览
  • preview-in-memory
    - 使用内存容器实现预览隔离
  • preview-static-data
    - 在模型类型上定义静态示例数据
  • preview-main-actor
    - 为SampleData添加@MainActor注解

How to Use

使用方法

Read individual reference files for detailed explanations and code examples:
  • Section definitions - Category structure and impact levels
  • Rule template - Template for adding new rules
阅读单个参考文件获取详细说明和代码示例:
  • 章节定义 - 类别结构和影响等级
  • 规则模板 - 添加新规则的模板

Reference Files

参考文件

FileDescription
references/_sections.mdCategory definitions and ordering
assets/templates/_template.mdTemplate for new rules
metadata.jsonVersion and reference information
文件描述
references/_sections.md类别定义与排序
assets/templates/_template.md新规则模板
metadata.json版本与参考信息