swiftdata-expert-skill について
AppleプラットフォームアプリのSwiftData永続化を構築、レビュー、改善するスキルです。デプロイ対象に応じたAPI選定、移行の安全性、同期、並行処理の分離を重視します。
主な機能
- 01デプロイ対象に応じたAPI案内
- 02モデルコンテナとコンテキストの診断
- 03スキーマ移行の計画
- 04CloudKit互換性の確認
- 05クエリと永続履歴の案内
- 06永続化コードレビューのリスク判定
活用シーン
- 01空の取得結果や挿入失敗の診断
- 02既存データを伴うスキーマ変更の計画
- 03CloudKit同期とモデル互換性のレビュー
- 04UIとバックグラウンド永続化処理の分離
インストール
コマンドをコピーしてターミナルで実行します。
$
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 エキスパートスキル
概要
このスキルは、iOS 17 から現在のアップデートまでの Apple 公式ドキュメントに基づくパターンを用いて、SwiftData の永続化アーキテクチャを構築、レビュー、強化するために使用します。データの整合性、マイグレーションの安全性、同期の正確性、予測可能な並行処理の動作を優先してください。
エージェントの行動規範(以下のルールに従ってください)
- 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()が必要かを確認します。 - Undo が有効か(
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を読みます。
- バックグラウンドでの分離、またはアクターベースの永続化が必要な場合:
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 スキーマとの互換性を確認してください。複数のコンテナがある場合は、
- ウィジェットや 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、オフセット、識別子のみのフェッチ)。 - 削除ルールをビジネスルールとして扱い、スキーマ変更時に見直してください。
- 環境固有の動作(メモリ内テスト、CloudKit、アプリグループ、読み取り専用ストア)には
ModelConfigurationを使用してください。 - 履歴を運用システムとして扱い、トークンの永続化、フィルタリング、クリーンアップを行ってください。
- UI 以外の永続化処理には、モデルアクターまたは隔離されたコンテキストを使用してください。
- API の利用可能性とデプロイメントターゲットに基づいて、推奨事項を適用してください。
変更後の検証チェックリスト
- 対象プラットフォームと最小デプロイメントバージョンでビルドが成功する。
- 実ストアおよびメモリ内ストアを使った CRUD テストが合格する。
- リレーションシップの削除が意図どおりに動作する(
cascade、nullifyなど)。 - 現実的なデータセットとソートまたはフィルターの組み合わせで、クエリの動作が安定している。
- 移行経路が既存データで検証されている(クリーンインストールだけでなく)。
- リリース前に、開発用コンテナで CloudKit の動作が検証されている。
- プロセス間の変更(ウィジェット、インテント、エクステンション)が正しく検知される。
- 破壊的操作のエラーパスとロールバック動作が網羅されている。
レスポンス契約
- レビュータスクでは、重大度の高い順に指摘事項を報告し、正確なファイルパスと行番号を含めてください。
- 実装タスクでは、以下を説明してください。
- コンテナーまたはコンテキストの変更
- スキーマまたはマイグレーションの変更
- クエリまたはパフォーマンスの変更
- 実施した検証手順と残された課題
- デプロイ先で推奨 API を利用できない場合は、現在のデプロイ先に対応する最適な代替策を提示してください。
コメント
Markdown 対応