关于 swiftdata-expert-skill
用于构建、审查和加固 Apple 平台应用中 SwiftData 持久化架构的技能,重点关注部署目标、迁移安全、同步正确性与并发隔离。
主要功能
- 01按部署目标提供 API 建议
- 02诊断模型容器与上下文
- 03规划架构迁移
- 04检查 CloudKit 兼容性
- 05指导查询与持久化历史
- 06识别持久化代码审查风险
适用场景
- 01排查查询为空或插入失败
- 02规划现有数据的架构变更
- 03审查 CloudKit 同步与模型兼容性
- 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.mdconcurrency-and-actors.mdcore-data-adoption.mdimplementation-playbooks.mdmigrations-and-history.mdmodel-context-and-lifecycle.mdmodeling-and-schema.mdquerying-and-fetching.mdrelationships-and-inheritance.mdtroubleshooting-and-updates.md详细介绍
SwiftData 专家技能
概述
使用此技能,按照 Apple 自 iOS 17 起至当前更新中记录的模式,构建、审查并强化 SwiftData 持久化架构。优先考虑数据完整性、迁移安全性、同步正确性和可预测的并发行为。
Agent 行为规范(遵循以下规则)
- 在推荐 API 前,先确认最低部署目标(尤其是
#Index、#Unique、HistoryDescriptor、DataStore和继承示例)。 - 调试数据问题前,确认应用已正确配置
ModelContainer;没有它,插入会失败,查询结果也会为空。 - 区分主线程隔离的 UI 操作与后台持久化操作;切勿假设两者适用同一个上下文。
- 将架构更改视为迁移更改:先评估轻量级迁移,必要时再使用
SchemaMigrationPlan。 - 对启用了 CloudKit 的应用,在提出模型更改建议前,先验证架构兼容性限制。
- 优先采用确定性的查询定义(共享谓词、明确的排序顺序、有界查询),而非在视图中临时筛选。
- 跨进程读取更改时使用持久化历史标记;删除过期历史,避免存储空间持续增长。
- 代码审查时,应优先关注数据丢失风险、意外的大规模删除、同步分歧和上下文隔离错误,而非代码风格更改。
分析命令(尽早使用)
- 搜索容器配置:
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 共存。
- 检查架构更改是否必须与现有用户数据保持向后兼容。
工作流决策树
- 需要新模型或架构形态:
- 阅读
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。
- 阅读
- 需要 iCloud 同步或 CloudKit 兼容性:
- 阅读
references/cloudkit-sync.md。
- 阅读
- 需要从 Core Data 渐进式迁移:
- 阅读
references/core-data-adoption.md。
- 阅读
- 需要后台隔离或基于 actor 的持久化:
- 阅读
references/concurrency-and-actors.md。
- 阅读
- 需要快速诊断或检查 API 可用性:
- 阅读
references/troubleshooting-and-updates.md。
- 阅读
- 需要针对具体任务的端到端执行手册:
- 阅读
references/implementation-playbooks.md。
优先分诊手册(常见问题 -> 下一步操作)
- 插入失败或获取结果始终为空:
- 确认
.modelContainer(...)已附加到应用或窗口根视图,并且已包含模型类型。
- 确认
- 网络刷新后出现重复行:
- 添加
@Attribute(.unique)或#Unique约束,并依赖插入时的更新行为。
- 添加
- 删除时意外丢失数据:
- 检查删除规则(
.cascade与.nullify),并检查是否存在无范围限制的delete(model:where:)。
- 检查删除规则(
- 撤销或重做不起作用:
- 确保
isUndoEnabled: true,并且通过mainContext保存更改(而不只是通过后台上下文)。
- 确保
- CloudKit 同步行为异常:
- 检查功能配置、远程通知和 CloudKit 架构兼容性;如果存在多个容器,请明确设置
cloudKitDatabase。
- 检查功能配置、远程通知和 CloudKit 架构兼容性;如果存在多个容器,请明确设置
- 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.mdreferences/model-context-and-lifecycle.mdreferences/querying-and-fetching.mdreferences/relationships-and-inheritance.mdreferences/migrations-and-history.mdreferences/cloudkit-sync.mdreferences/core-data-adoption.mdreferences/concurrency-and-actors.mdreferences/troubleshooting-and-updates.mdreferences/implementation-playbooks.md
最佳实践摘要
- 将模型代码作为唯一事实来源;避免依赖隐藏的架构假设。
- 为大型或频繁查询的数据集制定明确的唯一性和索引策略。
- 插入根模型,让 SwiftData 自动遍历关系图。
- 使用显式谓词和排序描述符,确保查询行为具有确定性。
- 限制获取范围(
fetchLimit、偏移量、仅标识符的获取),以便扩展。 - 将删除规则视为业务规则;在架构更改时进行检查。
- 使用
ModelConfiguration实现特定环境的行为(内存测试、CloudKit、应用组、只读存储)。 - 将历史记录作为运营系统来处理:持久化令牌、筛选和清理。
- 对非 UI 持久化工作使用模型 Actor 或隔离上下文。
- 根据 API 可用性和部署目标设置建议门槛。
验证清单(更改后)
- 针对目标平台和最低部署版本的构建成功。
- 使用真实存储和内存存储的 CRUD 测试通过。
- 关系删除行为符合预期(
cascade、nullify等)。 - 使用真实数据集以及排序或筛选组合时,查询行为保持稳定。
- 在已有数据上验证迁移路径(而不只是全新安装)。
- 发布前在开发容器中验证 CloudKit 行为。
- 正确观察跨进程更改(Widget、Intent、扩展)。
- 为破坏性操作覆盖错误路径和回滚行为。
响应约定
- 对于审查任务,先按严重性报告发现的问题,并注明准确的文件路径和行号。
- 对于实现任务,请说明:
- 容器或上下文变更,
- 架构或迁移变更,
- 查询或性能变更,
- 已运行的验证步骤及任何未覆盖之处。
- 如果部署目标不支持推荐的 API,请提供与当前目标兼容的最佳替代方案。
评论
支持 Markdown