mcpField
S
swiftdata-expert-skill

swiftdata-expert-skill

github.com/vanab開発14324 回インストール37 週間前に更新
リポジトリ

swiftdata-expert-skill について

AppleプラットフォームアプリのSwiftData永続化を構築、レビュー、改善するスキルです。デプロイ対象に応じたAPI選定、移行の安全性、同期、並行処理の分離を重視します。

主な機能

  1. 01デプロイ対象に応じたAPI案内
  2. 02モデルコンテナとコンテキストの診断
  3. 03スキーマ移行の計画
  4. 04CloudKit互換性の確認
  5. 05クエリと永続履歴の案内
  6. 06永続化コードレビューのリスク判定

活用シーン

  1. 01空の取得結果や挿入失敗の診断
  2. 02既存データを伴うスキーマ変更の計画
  3. 03CloudKit同期とモデル互換性のレビュー
  4. 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.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 エキスパートスキル

概要

このスキルは、iOS 17 から現在のアップデートまでの Apple 公式ドキュメントに基づくパターンを用いて、SwiftData の永続化アーキテクチャを構築、レビュー、強化するために使用します。データの整合性、マイグレーションの安全性、同期の正確性、予測可能な並行処理の動作を優先してください。

エージェントの行動規範(以下のルールに従ってください)

  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() が必要かを確認します。
  • Undo が有効か(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. バックグラウンドでの分離、またはアクターベースの永続化が必要な場合:
    • 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 を明示的に設定してください。
  • ウィジェットや 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. 環境固有の動作(メモリ内テスト、CloudKit、アプリグループ、読み取り専用ストア)には ModelConfiguration を使用してください。
  8. 履歴を運用システムとして扱い、トークンの永続化、フィルタリング、クリーンアップを行ってください。
  9. UI 以外の永続化処理には、モデルアクターまたは隔離されたコンテキストを使用してください。
  10. API の利用可能性とデプロイメントターゲットに基づいて、推奨事項を適用してください。

変更後の検証チェックリスト

  • 対象プラットフォームと最小デプロイメントバージョンでビルドが成功する。
  • 実ストアおよびメモリ内ストアを使った CRUD テストが合格する。
  • リレーションシップの削除が意図どおりに動作する(cascade、nullify など)。
  • 現実的なデータセットとソートまたはフィルターの組み合わせで、クエリの動作が安定している。
  • 移行経路が既存データで検証されている(クリーンインストールだけでなく)。
  • リリース前に、開発用コンテナで CloudKit の動作が検証されている。
  • プロセス間の変更(ウィジェット、インテント、エクステンション)が正しく検知される。
  • 破壊的操作のエラーパスとロールバック動作が網羅されている。

レスポンス契約

  • レビュータスクでは、重大度の高い順に指摘事項を報告し、正確なファイルパスと行番号を含めてください。
  • 実装タスクでは、以下を説明してください。
    • コンテナーまたはコンテキストの変更
    • スキーマまたはマイグレーションの変更
    • クエリまたはパフォーマンスの変更
    • 実施した検証手順と残された課題
  • デプロイ先で推奨 API を利用できない場合は、現在のデプロイ先に対応する最適な代替策を提示してください。

コメント