mcpField
S
swiftdata-expert-skill

swiftdata-expert-skill

github.com/vanab开发14324 次安装37 周前更新
代码仓库

关于 swiftdata-expert-skill

用于构建、审查和加固 Apple 平台应用中 SwiftData 持久化架构的技能,重点关注部署目标、迁移安全、同步正确性与并发隔离。

主要功能

  1. 01按部署目标提供 API 建议
  2. 02诊断模型容器与上下文
  3. 03规划架构迁移
  4. 04检查 CloudKit 兼容性
  5. 05指导查询与持久化历史
  6. 06识别持久化代码审查风险

适用场景

  1. 01排查查询为空或插入失败
  2. 02规划现有数据的架构变更
  3. 03审查 CloudKit 同步与模型兼容性
  4. 04隔离 UI 与后台持久化操作

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/vanab/swiftdata-agent-skill --skill swiftdata-expert-skill

安装后在 Claude Code 中输入/swiftdata-expert-skill确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

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

详细介绍

SwiftData 专家技能

概述

使用此技能,按照 Apple 自 iOS 17 起至当前更新中记录的模式,构建、审查并强化 SwiftData 持久化架构。优先考虑数据完整性、迁移安全性、同步正确性和可预测的并发行为。

Agent 行为规范(遵循以下规则)

  1. 在推荐 API 前,先确认最低部署目标(尤其是 #Index、#Unique、HistoryDescriptor、DataStore 和继承示例)。
  2. 调试数据问题前,确认应用已正确配置 ModelContainer;没有它,插入会失败,查询结果也会为空。
  3. 区分主线程隔离的 UI 操作与后台持久化操作;切勿假设两者适用同一个上下文。
  4. 将架构更改视为迁移更改:先评估轻量级迁移,必要时再使用 SchemaMigrationPlan。
  5. 对启用了 CloudKit 的应用,在提出模型更改建议前,先验证架构兼容性限制。
  6. 优先采用确定性的查询定义(共享谓词、明确的排序顺序、有界查询),而非在视图中临时筛选。
  7. 跨进程读取更改时使用持久化历史标记;删除过期历史,避免存储空间持续增长。
  8. 代码审查时,应优先关注数据丢失风险、意外的大规模删除、同步分歧和上下文隔离错误,而非代码风格更改。

分析命令(尽早使用)

  • 搜索容器配置:
    • 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

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

  • 确定部署目标:iOS、iPadOS、macOS、watchOS 和 visionOS。
  • 找到容器配置:.modelContainer(...) 修饰符或手动创建的 ModelContainer(...)。
  • 确认是否需要自动保存,以及是否需要显式调用 save()。
  • 检查是否启用了撤销(isUndoEnabled),以及操作发生在 mainContext 还是自定义上下文中。
  • 检查 CloudKit 功能和所选容器策略(automatic、.private(...)、.none)。
  • 检查是否需要应用组存储。
  • 检查是否涉及与 Core Data 共存。
  • 检查架构更改是否必须与现有用户数据保持向后兼容。

工作流决策树

  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。

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

  • 插入失败或获取结果始终为空:
    • 确认 .modelContainer(...) 已附加到应用或窗口根视图,并且已包含模型类型。
  • 网络刷新后出现重复行:
    • 添加 @Attribute(.unique) 或 #Unique 约束,并依赖插入时的更新行为。
  • 删除时意外丢失数据:
    • 检查删除规则(.cascade 与 .nullify),并检查是否存在无范围限制的 delete(model:where:)。
  • 撤销或重做不起作用:
    • 确保 isUndoEnabled: true,并且通过 mainContext 保存更改(而不只是通过后台上下文)。
  • CloudKit 同步行为异常:
    • 检查功能配置、远程通知和 CloudKit 架构兼容性;如果存在多个容器,请明确设置 cloudKitDatabase。
  • Widget 或 App Intent 的更改未反映出来:
    • 使用持久化历史(fetchHistory),并按令牌和作者进行筛选。
  • 出现 historyTokenExpired:
    • 重置本地令牌策略,并从安全的位置重新启动变更消费。
  • 查询结果开销大或不稳定:
    • 使用共享谓词构建器、显式排序,以及范围受限的 FetchDescriptor 设置。

反模式(默认拒绝)

  • 未验证容器配置就开始构建持久化逻辑。
  • 未审核谓词并确认,就执行大范围删除。
  • 混合由 UI 驱动的编辑和后台写入管线,却未设置隔离边界。
  • 依赖临时的内存筛选,而不使用存储支持的谓词。
  • 未配置功能或检查架构兼容性,就启用 CloudKit 同步。
  • 未在现有用户数据上演练迁移,就发布架构更改。
  • 消费历史记录时未持久化令牌,也未制定清理策略。

核心模式

应用级容器配置(SwiftUI)
@main
struct MyApp: App {
    var body: some Scene {
        WindowGroup {
            RootView()
        }
        .modelContainer(for: [Trip.self, Accommodation.self])
    }
}
手动配置容器
let config = ModelConfiguration(isStoredInMemoryOnly: false)
let container = try ModelContainer(
    for: Trip.self,
    Accommodation.self,
    configurations: config
)
在视图初始化器中动态设置查询
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) } }
}
安全的批量删除模式
do {
    try modelContext.delete(
        model: Trip.self,
        where: #Predicate { $0.endDate < .now },
        includeSubclasses: true
    )
    try modelContext.save()
} catch {
    // Handle delete and save failures.
}

参考文件

  • 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

最佳实践摘要

  1. 将模型代码作为唯一事实来源;避免依赖隐藏的架构假设。
  2. 为大型或频繁查询的数据集制定明确的唯一性和索引策略。
  3. 插入根模型,让 SwiftData 自动遍历关系图。
  4. 使用显式谓词和排序描述符,确保查询行为具有确定性。
  5. 限制获取范围(fetchLimit、偏移量、仅标识符的获取),以便扩展。
  6. 将删除规则视为业务规则;在架构更改时进行检查。
  7. 使用 ModelConfiguration 实现特定环境的行为(内存测试、CloudKit、应用组、只读存储)。
  8. 将历史记录作为运营系统来处理:持久化令牌、筛选和清理。
  9. 对非 UI 持久化工作使用模型 Actor 或隔离上下文。
  10. 根据 API 可用性和部署目标设置建议门槛。

验证清单(更改后)

  • 针对目标平台和最低部署版本的构建成功。
  • 使用真实存储和内存存储的 CRUD 测试通过。
  • 关系删除行为符合预期(cascade、nullify 等)。
  • 使用真实数据集以及排序或筛选组合时,查询行为保持稳定。
  • 在已有数据上验证迁移路径(而不只是全新安装)。
  • 发布前在开发容器中验证 CloudKit 行为。
  • 正确观察跨进程更改(Widget、Intent、扩展)。
  • 为破坏性操作覆盖错误路径和回滚行为。

响应约定

  • 对于审查任务,先按严重性报告发现的问题,并注明准确的文件路径和行号。
  • 对于实现任务,请说明:
    • 容器或上下文变更,
    • 架构或迁移变更,
    • 查询或性能变更,
    • 已运行的验证步骤及任何未覆盖之处。
  • 如果部署目标不支持推荐的 API,请提供与当前目标兼容的最佳替代方案。

评论

支持 Markdown