名称: swift-data 描述: SwiftData持久化和数据层架构,适用于iOS 26 / Swift 6.2诊所模块化MVVM-C应用程序。在编写、审查或重构@Model实体、存储库实现、陈旧-同时-重新验证读取、乐观队列写入、同步/重试行为以及保持SwiftData类型仅在数据边界内的SwiftUI集成时使用。
SwiftData最佳实践 — 模块化MVVM-C数据层
全面的数据建模、持久化、同步架构和错误处理指南,与诊所模块化MVVM-C堆栈对齐的SwiftData。
架构对齐
这个技能强制执行与swift-ui-architect相同的模块化架构:
┌───────────────────────────────────────────────────────────────┐
│ 功能模块: 视图 + 视图模型,无SwiftData导入 │
├───────────────────────────────────────────────────────────────┤
│ 领域: 模型 + 存储库/协调器/错误协议 │
├───────────────────────────────────────────────────────────────┤
│ 数据: @Model实体,SwiftData存储,存储库实现, │
│ 远程客户端,重试执行器,同步队列,冲突处理 │
└───────────────────────────────────────────────────────────────┘
关键原则: SwiftData类型(@Model, ModelContext, @Query, FetchDescriptor)仅存在于数据层实现代码中。功能视图/视图模型使用领域类型和协议依赖工作。
诊所架构合约(iOS 26 / Swift 6.2)
本技能中的所有指导都假设诊所模块化MVVM-C架构:
- 功能模块仅导入
领域+设计系统(从不导入数据,从不导入兄弟功能) - 应用目标是汇聚点,并拥有
依赖容器、具体协调器和路由外壳连线 领域保持纯Swift,并定义模型以及存储库、*协调、错误路由和应用错误合约数据拥有SwiftData/网络/同步/重试/后台I/O,并实现领域协议- 读/写流默认使用陈旧-同时-重新验证读取和乐观队列写入
- 视图模型直接调用存储库协议(无默认用例/交互器层)
何时应用
在以下情况下参考这些指南:
- 定义@Model实体类并将其映射到领域结构体
- 在数据层设置ModelContainer和ModelContext
- 实现基于SwiftData的存储库协议
- 编写陈旧-同时-重新验证存储库读取(
AsyncStream) - 实现乐观写入加上队列同步操作
- 配置实体关系(一对多,逆关系)
- 从API获取并通过同步协调器持久化到SwiftData
- 处理保存失败、损坏存储和迁移错误
- 将AppError特征路由到集中式错误UI基础设施
- 使用样本数据构建预览基础设施
- 为应用更新规划模式迁移
工作流
在设计或重构基于SwiftData的功能时使用此工作流:
- 领域设计:定义领域结构体(
Trip,Friend)和验证/计算规则(见model-domain-mapping,state-business-logic-placement) - 实体设计:定义具有映射方法的
@Model实体类(见model-*,model-domain-mapping) - 存储库协议:在领域层定义,在数据层用SwiftData实现(见
persist-repository-wrapper) - 容器连线:在应用边界配置
ModelContainer一次,带错误恢复(见persist-container-setup,persist-container-error-recovery) - 依赖注入:通过@Environment注入存储库协议(见
state-dependency-injection) - 视图模型:创建@Observable视图模型,直接委托给存储库协议(见
state-query-vs-viewmodel) - CRUD流:将所有插入/删除/更新通过视图模型 -> 存储库路由(见
crud-*) - 同步架构:队列写入,通过带重试策略的同步协调器执行(见
sync-*) - 关系:将多对多关系建模为数组;定义删除规则(见
rel-*) - 预览:创建内存容器和样本数据以快速迭代(见
preview-*) - 模式进化:规划带版本化模式的迁移(见
schema-*)
故障排除
- 数据未持久化 ->
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 - 小部件/扩展无法看到数据 ->
persist-app-group,schema-configuration - 为数据视图选择架构模式 ->
state-query-vs-viewmodel,persist-repository-wrapper
按优先级分类的规则类别
| 优先级 | 类别 | 影响 | 前缀 |
|---|---|---|---|
| 1 | 数据建模 | 关键 | model- |
| 2 | 持久化设置 | 关键 | persist- |
| 3 | 查询与过滤 | 高 | query- |
| 4 | CRUD操作 | 高 | crud- |
| 5 | 同步与网络 | 高 | sync- |
| 6 | 关系 | 中-高 | rel- |
| 7 | SwiftUI状态流 | 中-高 | state- |
| 8 | 模式与迁移 | 中-高 | schema- |
| 9 | 样本数据与预览 | 中 | preview- |
快速参考
1. 数据建模(关键)
model-domain-mapping- 跨领域/数据边界将@Model实体映射到领域结构体model-custom-types- 使用自定义类型而非并行数组model-class-for-persistence- 对SwiftData实体类型使用类model-identifiable- 使用UUID使实体符合Identifiablemodel-initializer- 为实体类提供自定义初始化器model-computed-properties- 使用计算属性用于派生数据model-defaults- 为实体属性提供合理的默认值model-transient- 用@Transient标记非持久属性model-external-storage- 对大二进制数据使用外部存储
2. 持久化设置(关键)
persist-repository-wrapper- 在领域存储库协议后包装SwiftDatapersist-model-macro- 对所有持久类型应用@Model宏persist-container-setup- 在应用级别配置ModelContainerpersist-container-error-recovery- 使用存储恢复处理ModelContainer创建失败persist-context-environment- 通过@Environment访问ModelContext(数据层)persist-autosave- 为手动创建的上下文启用自动保存persist-enumerate-batch- 对大遍历使用ModelContext.enumeratepersist-in-memory-config- 对测试和预览使用内存配置persist-app-group- 对共享数据存储使用应用组persist-model-actor- 使用@ModelActor进行后台SwiftData工作persist-identifier-transfer- 跨执行器传递PersistentIdentifier
3. 查询与过滤(高)
query-property-wrapper- 对声明式数据获取使用@Query(数据层)query-background-refresh- 后台上下文插入后强制视图刷新query-sort-descriptors- 对@Query应用排序描述符query-predicates- 使用#Predicate进行类型安全过滤query-dynamic-init- 对动态查询使用自定义视图初始化器query-fetch-descriptor- 在SwiftUI视图外使用FetchDescriptorquery-fetch-tuning- 调整FetchDescriptor分页和待更改行为query-localized-search- 对搜索使用localizedStandardContainsquery-expression- 对可重用谓词组件使用#Expression(iOS 18+)
4. CRUD操作(高)
crud-insert-context- 通过存储库实现插入模型crud-delete-indexset- 通过onDelete的IndexSet通过存储库删除crud-sheet-creation- 对通过视图模型的聚焦数据创建使用表单crud-cancel-delete- 避免孤立记录,仅在保存时持久化crud-undo-cancel- 启用撤销并用其取消编辑crud-edit-button- 提供EditButton用于列表管理crud-dismiss-save- 视图模型保存完成后关闭模态crud-save-error-handling- 用用户反馈处理存储库保存失败
5. 同步与网络(高)
sync-fetch-persist- 使用注入的同步服务获取并持久化API数据sync-offline-first- 设计带存储库读取和后台同步的离线优先架构sync-conflict-resolution- 实现双向同步的冲突解决
6. 关系(中-高)
rel-optional-single- 对可选关系使用可选rel-array-many- 对一对多关系使用数组rel-inverse-auto- 依赖SwiftData自动逆维护rel-delete-rules- 为拥有关系配置级联删除规则rel-explicit-sort- 显式排序关系数组
7. SwiftUI状态流(中-高)
state-query-vs-viewmodel- 通过@Observable视图模型路由所有数据访问state-business-logic-placement- 将业务逻辑放在领域值类型和存储库支持的视图模型中state-dependency-injection- 通过@Environment注入存储库协议state-bindable- 对双向模型绑定使用@Bindablestate-local-state- 对视图本地瞬态数据使用@Statestate-wrapper-views- 提取包装器视图用于动态查询状态
8. 模式与迁移(中-高)
schema-define-all-types- 用所有模型类型定义模式schema-unique-attributes- 对自然键使用@Attribute(.unique)schema-unique-macro- 对复合唯一性使用#Unique(iOS 18+)schema-index- 对热门谓词和排序使用#Index(iOS 18+)schema-migration-plan- 更改模型前规划迁移schema-migration-recovery- 为模式更改规划迁移恢复schema-configuration- 用ModelConfiguration自定义存储
9. 样本数据与预览(中)
preview-sample-singleton- 为预览创建SampleData单例preview-in-memory- 对预览隔离使用内存容器preview-static-data- 在模型类型上定义静态样本数据preview-main-actor- 用@MainActor注释SampleData
如何使用
阅读个别参考文件获取详细解释和代码示例:
参考文件
| 文件 | 描述 |
|---|---|
| references/_sections.md | 类别定义和排序 |
| assets/templates/_template.md | 新规则的模板 |
| metadata.json | 版本和参考信息 |