swiftdata-expert-skill

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

SwiftData Expert Skill

SwiftData 专家技能

Overview

概述

Use this skill to build, review, and harden SwiftData persistence architecture with Apple-documented patterns from iOS 17 through current updates. Prioritize data integrity, migration safety, sync correctness, and predictable concurrency behavior.
使用本技能,结合iOS 17及后续版本中苹果官方文档记载的模式,构建、评审并强化SwiftData持久化架构。优先保障数据完整性、迁移安全性、同步正确性及可预测的并发行为。

Agent Behavior Contract (Follow These Rules)

Agent 行为约定(请遵循以下规则)

  1. Identify the minimum deployment target before recommending APIs (notably
    #Index
    ,
    #Unique
    ,
    HistoryDescriptor
    ,
    DataStore
    , inheritance examples).
  2. Confirm the app has real
    ModelContainer
    wiring before debugging data issues; without it, inserts fail and fetches are empty.
  3. Distinguish main-actor UI operations from background persistence operations; never assume one context fits both.
  4. Treat schema changes as migration changes: evaluate lightweight migration first, then
    SchemaMigrationPlan
    when needed.
  5. For CloudKit-enabled apps, verify schema compatibility constraints before proposing model changes.
  6. Prefer deterministic query definitions (shared predicates, explicit sort order, bounded fetches) over ad hoc filtering in views.
  7. Use persistent history tokens when reading cross-process changes; delete stale history to avoid storage growth.
  8. In code reviews, prioritize data loss risk, accidental mass deletion, sync divergence, and context-isolation bugs over style changes.
  1. 在推荐API前先确认最低部署目标(尤其是
    #Index
    #Unique
    HistoryDescriptor
    DataStore
    、继承示例等)。
  2. 调试数据问题前,先确认应用已正确配置
    ModelContainer
    ;若未配置,数据插入会失败,查询结果为空。
  3. 区分主线程UI操作与后台持久化操作;切勿假设单个上下文可同时适配两种场景。
  4. 将架构变更视为迁移变更:优先评估轻量迁移,必要时再使用
    SchemaMigrationPlan
  5. 对于启用CloudKit的应用,在提议模型变更前先验证架构兼容性约束。
  6. 优先使用确定性查询定义(共享谓词、显式排序、有限查询),而非视图中的临时过滤。
  7. 读取跨进程变更时使用持久化历史令牌;删除过期历史记录以避免存储容量膨胀。
  8. 代码评审时,优先关注数据丢失风险、意外批量删除、同步分歧及上下文隔离漏洞,而非代码风格变更。

Analysis Commands (Use Early)

分析命令(尽早使用)

  • Search container setup:
    • rg "modelContainer\\(|ModelContainer\\(" -n
  • Search model definitions:
    • rg "^@Model|#Unique|#Index|@Relationship|@Attribute|@Transient" -n
  • Search context usage:
    • rg "modelContext|mainContext|ModelContext\\(" -n
  • Search migrations and history:
    • rg "SchemaMigrationPlan|VersionedSchema|MigrationStage|fetchHistory|deleteHistory|historyToken" -n
  • Search CloudKit and app groups:
    • rg "cloudKitDatabase|iCloud|CloudKit|groupContainer|AppGroup|NSPersistentCloudKitContainer" -n
  • 搜索容器配置:
    • rg "modelContainer\\(|ModelContainer\\(" -n
  • 搜索模型定义:
    • rg "^@Model|#Unique|#Index|@Relationship|@Attribute|@Transient" -n
  • 搜索上下文使用情况:
    • rg "modelContext|mainContext|ModelContext\\(" -n
  • 搜索迁移与历史记录:
    • rg "SchemaMigrationPlan|VersionedSchema|MigrationStage|fetchHistory|deleteHistory|historyToken" -n
  • 搜索CloudKit与应用组:
    • rg "cloudKitDatabase|iCloud|CloudKit|groupContainer|AppGroup|NSPersistentCloudKitContainer" -n

Project Intake (Before Advising)

项目信息收集(提供建议前)

  • Determine deployment targets: iOS, iPadOS, macOS, watchOS, and visionOS.
  • Locate container setup:
    .modelContainer(...)
    modifier or manual
    ModelContainer(...)
    .
  • Verify whether autosave is expected and whether explicit
    save()
    is required.
  • Check if undo is enabled (
    isUndoEnabled
    ) and whether operations occur on
    mainContext
    or custom contexts.
  • Check CloudKit capabilities and chosen container strategy (
    automatic
    ,
    .private(...)
    ,
    .none
    ).
  • Check if app group storage is required.
  • Check if Core Data coexistence is in scope.
  • Check if schema changes must be backward-compatible with existing user data.
  • 确定部署目标:iOS、iPadOS、macOS、watchOS及visionOS。
  • 定位容器配置位置:
    .modelContainer(...)
    修饰器或手动配置的
    ModelContainer(...)
  • 确认是否需要自动保存,以及是否需要显式调用
    save()
  • 检查是否启用了撤销功能(
    isUndoEnabled
    ),以及操作是在
    mainContext
    还是自定义上下文中执行。
  • 检查CloudKit功能及所选容器策略(
    automatic
    .private(...)
    .none
    )。
  • 检查是否需要应用组存储。
  • 检查是否涉及Core Data共存场景。
  • 检查架构变更是否必须与现有用户数据向后兼容。

Workflow Decision Tree

工作流决策树

  1. Need a new model or schema shape:
    • Read
      references/modeling-and-schema.md
      .
  2. Need create, update, delete behavior or context correctness:
    • Read
      references/model-context-and-lifecycle.md
      .
  3. Need filtering, sorting, or dynamic list behavior:
    • Read
      references/querying-and-fetching.md
      .
  4. Need relationship modeling or inheritance:
    • Read
      references/relationships-and-inheritance.md
      .
  5. Need migration planning, release upgrades, or change tracking:
    • Read
      references/migrations-and-history.md
      .
  6. Need iCloud sync or CloudKit compatibility:
    • Read
      references/cloudkit-sync.md
      .
  7. Need incremental migration from Core Data:
    • Read
      references/core-data-adoption.md
      .
  8. Need background isolation or actor-based persistence:
    • Read
      references/concurrency-and-actors.md
      .
  9. Need quick diagnostics or API availability checks:
    • Read
      references/troubleshooting-and-updates.md
      .
  10. Need end-to-end execution playbook for a concrete task:
  • Read
    references/implementation-playbooks.md
    .
  1. 若需创建新模型或调整架构形态:
    • 阅读
      references/modeling-and-schema.md
  2. 若需实现增删改查行为或确保上下文正确性:
    • 阅读
      references/model-context-and-lifecycle.md
  3. 若需实现过滤、排序或动态列表行为:
    • 阅读
      references/querying-and-fetching.md
  4. 若需建模关系或实现继承:
    • 阅读
      references/relationships-and-inheritance.md
  5. 若需规划迁移、版本升级或变更跟踪:
    • 阅读
      references/migrations-and-history.md
  6. 若需实现iCloud同步或保障CloudKit兼容性:
    • 阅读
      references/cloudkit-sync.md
  7. 若需从Core Data逐步迁移:
    • 阅读
      references/core-data-adoption.md
  8. 若需实现后台隔离或基于Actor的持久化:
    • 阅读
      references/concurrency-and-actors.md
  9. 若需快速诊断或检查API可用性:
    • 阅读
      references/troubleshooting-and-updates.md
  10. 若需针对具体任务的端到端执行手册:
    • 阅读
      references/implementation-playbooks.md

Triage-First Playbook (Common Problems -> Next Move)

优先排查手册(常见问题 -> 下一步操作)

  • Insert fails or fetch is always empty:
    • Confirm
      .modelContainer(...)
      is attached at app or window root and the model type is included.
  • Duplicate rows appear after network refresh:
    • Add
      @Attribute(.unique)
      or
      #Unique
      constraints and rely on insert-upsert behavior.
  • Unexpected data loss during delete:
    • Audit delete rules (
      .cascade
      vs
      .nullify
      ) and check for unbounded
      delete(model:where:)
      .
  • Undo or redo does nothing:
    • Ensure
      isUndoEnabled: true
      and that changes are saved via
      mainContext
      (not only background context).
  • CloudKit sync not behaving:
    • Check capabilities, remote notifications, and CloudKit schema compatibility; explicitly set
      cloudKitDatabase
      if multiple containers exist.
  • Widget or App Intent changes are not reflected:
    • Use persistent history (
      fetchHistory
      ) with token + author filtering.
  • historyTokenExpired
    appears:
    • Reset local token strategy and rebootstrap change consumption from a safe point.
  • Query results are expensive or unstable:
    • Use shared predicate builders, explicit sorting, and bounded
      FetchDescriptor
      settings.
  • 插入失败或查询结果始终为空:
    • 确认
      .modelContainer(...)
      已附加到应用或窗口根节点,且包含了对应的模型类型。
  • 网络刷新后出现重复行:
    • 添加
      @Attribute(.unique)
      #Unique
      约束,利用插入-更新的特性。
  • 删除时出现意外数据丢失:
    • 审核删除规则(
      .cascade
      vs
      .nullify
      ),并检查是否存在无限制的
      delete(model:where:)
      调用。
  • 撤销或重做操作无响应:
    • 确保
      isUndoEnabled: true
      ,且变更通过
      mainContext
      保存(而非仅通过后台上下文)。
  • CloudKit同步行为异常:
    • 检查功能配置、远程通知及CloudKit架构兼容性;若存在多个容器,显式设置
      cloudKitDatabase
  • Widget或App Intent变更未同步显示:
    • 使用带令牌+作者过滤的持久化历史记录(
      fetchHistory
      )。
  • 出现
    historyTokenExpired
    错误:
    • 重置本地令牌策略,从安全节点重新启动变更消费流程。
  • 查询结果性能低下或不稳定:
    • 使用共享谓词构建器、显式排序及有限制的
      FetchDescriptor
      设置。

Anti-Patterns (Reject by Default)

反模式(默认拒绝)

  • Building persistence logic before validating container wiring.
  • Performing broad deletes without predicate review and confirmation.
  • Mixing UI-driven editing and background write pipelines without isolation boundaries.
  • Relying on ad hoc in-memory filtering instead of store-backed predicates.
  • Enabling CloudKit sync without capability setup and schema compatibility checks.
  • Shipping schema changes without migration rehearsal on existing user data.
  • Consuming history without token persistence and cleanup policy.
  • 在验证容器配置前就构建持久化逻辑。
  • 未评审谓词就执行大范围删除操作。
  • 未设置隔离边界就混合UI驱动的编辑与后台写入流程。
  • 依赖临时内存过滤而非存储端谓词。
  • 未完成功能配置与架构兼容性检查就启用CloudKit同步。
  • 未在现有用户数据上演练迁移就发布架构变更。
  • 未设置令牌持久化与清理策略就消费历史记录。

Core Patterns

核心模式

App-level container wiring (SwiftUI)

应用级容器配置(SwiftUI)

swift
@main
struct MyApp: App {
    var body: some Scene {
        WindowGroup {
            RootView()
        }
        .modelContainer(for: [Trip.self, Accommodation.self])
    }
}
swift
@main
struct MyApp: App {
    var body: some Scene {
        WindowGroup {
            RootView()
        }
        .modelContainer(for: [Trip.self, Accommodation.self])
    }
}

Manual container configuration

手动容器配置

swift
let config = ModelConfiguration(isStoredInMemoryOnly: false)
let container = try ModelContainer(
    for: Trip.self,
    Accommodation.self,
    configurations: config
)
swift
let config = ModelConfiguration(isStoredInMemoryOnly: false)
let container = try ModelContainer(
    for: Trip.self,
    Accommodation.self,
    configurations: config
)

Dynamic query setup in a view initializer

视图初始化器中的动态查询配置

swift
struct TripListView: View {
    @Query private var trips: [Trip]

    init(searchText: String) {
        let predicate = #Predicate<Trip> {
            searchText.isEmpty || $0.name.localizedStandardContains(searchText)
        }
        _trips = Query(filter: predicate, sort: \.startDate, order: .forward)
    }

    var body: some View { List(trips) { Text($0.name) } }
}
swift
struct TripListView: View {
    @Query private var trips: [Trip]

    init(searchText: String) {
        let predicate = #Predicate<Trip> {
            searchText.isEmpty || $0.name.localizedStandardContains(searchText)
        }
        _trips = Query(filter: predicate, sort: \.startDate, order: .forward)
    }

    var body: some View { List(trips) { Text($0.name) } }
}

Safe batch delete pattern

安全批量删除模式

swift
do {
    try modelContext.delete(
        model: Trip.self,
        where: #Predicate { $0.endDate < .now },
        includeSubclasses: true
    )
    try modelContext.save()
} catch {
    // Handle delete and save failures.
}
swift
do {
    try modelContext.delete(
        model: Trip.self,
        where: #Predicate { $0.endDate < .now },
        includeSubclasses: true
    )
    try modelContext.save()
} catch {
    // Handle delete and save failures.
}

Reference Files

参考文档

  • references/modeling-and-schema.md
  • references/model-context-and-lifecycle.md
  • references/querying-and-fetching.md
  • references/relationships-and-inheritance.md
  • references/migrations-and-history.md
  • references/cloudkit-sync.md
  • references/core-data-adoption.md
  • references/concurrency-and-actors.md
  • references/troubleshooting-and-updates.md
  • references/implementation-playbooks.md
  • references/modeling-and-schema.md
  • references/model-context-and-lifecycle.md
  • references/querying-and-fetching.md
  • references/relationships-and-inheritance.md
  • references/migrations-and-history.md
  • references/cloudkit-sync.md
  • references/core-data-adoption.md
  • references/concurrency-and-actors.md
  • references/troubleshooting-and-updates.md
  • references/implementation-playbooks.md

Best Practices Summary

最佳实践总结

  1. Keep model code as the source of truth; avoid hidden schema assumptions.
  2. Apply explicit uniqueness and indexing strategy for large or frequently queried datasets.
  3. Insert root models and let SwiftData traverse relationship graphs automatically.
  4. Keep query behavior deterministic with explicit predicates and sort descriptors.
  5. Bound fetches (
    fetchLimit
    , offsets, identifier-only fetches) for scalability.
  6. Treat delete rules as business rules; review them during schema changes.
  7. Use
    ModelConfiguration
    for environment-specific behavior (in-memory tests, CloudKit, app groups, read-only stores).
  8. Handle history as an operational system: token persistence, filtering, and cleanup.
  9. Use model actors or isolated contexts for non-UI persistence work.
  10. Gate recommendations by API availability and deployment target.
  1. 将模型代码作为唯一可信来源;避免隐藏的架构假设。
  2. 针对大型或频繁查询的数据集,应用显式的唯一性与索引策略。
  3. 插入根模型,让SwiftData自动遍历关系图。
  4. 通过显式谓词与排序描述符确保查询行为的确定性。
  5. 为查询设置限制(
    fetchLimit
    、偏移量、仅获取标识符)以提升可扩展性。
  6. 将删除规则视为业务规则;在架构变更时进行评审。
  7. 使用
    ModelConfiguration
    实现环境特定行为(内存测试、CloudKit、应用组、只读存储)。
  8. 将历史记录视为操作系统:实现令牌持久化、过滤与清理。
  9. 对于非UI持久化工作,使用Model Actor或隔离上下文。
  10. 根据API可用性与部署目标调整推荐方案。

Verification Checklist (After Changes)

验证清单(变更后)

  • Build succeeds for target platforms and minimum deployment versions.
  • CRUD tests pass with real store and in-memory store.
  • Relationship deletes behave as intended (
    cascade
    ,
    nullify
    , and others).
  • Query behavior is stable with realistic datasets and sort or filter combinations.
  • Migration path is validated on pre-existing data (not only clean installs).
  • CloudKit behavior is validated in a development container before release.
  • Cross-process changes (widgets, intents, extensions) are observed correctly.
  • Error paths and rollback behavior are covered for destructive operations.
  • 针对目标平台与最低部署版本,构建成功。
  • CRUD测试在真实存储与内存存储中均通过。
  • 关系删除行为符合预期(
    cascade
    nullify
    等)。
  • 在真实数据集及各种排序或过滤组合下,查询行为稳定。
  • 在已有数据(而非仅全新安装)上验证迁移路径。
  • 发布前在开发容器中验证CloudKit行为。
  • 跨进程变更(Widget、Intent、扩展)能被正确识别。
  • 破坏性操作的错误路径与回滚行为已覆盖。

Response Contract

响应约定

  • For review tasks, report findings first by severity and include exact file paths and lines.
  • For implementation tasks, describe:
    • container or context changes,
    • schema or migration changes,
    • query or performance changes,
    • verification steps run and any gaps.
  • If deployment target blocks a recommended API, provide the best fallback compatible with the current target.
  • 对于评审任务,先按严重程度报告发现的问题,并包含精确的文件路径与行号。
  • 对于实现任务,描述:
    • 容器或上下文变更,
    • 架构或迁移变更,
    • 查询或性能变更,
    • 已执行的验证步骤及任何遗漏点。
  • 若部署目标限制了推荐的API,提供与当前目标兼容的最佳替代方案。