Skip to content
Development
Skill

/swiftdata

Implement, review, or improve data persistence using SwiftData. Use when defining @Model classes with @Attribute, @Relationship, @Transient, #Unique, or #Index; when querying with @Query, #Predicate, FetchDescriptor, or SortDescriptor; when configuring ModelContainer and

From plugin
swift-ios-skills
98186 skills1 MCP
Install
$ npx -y skills add dpearson2699/swift-ios-skills --skill swiftdata --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/swiftdata

Context preview

The summary Claude sees to decide when to auto-load this skill.

Implement, review, or improve data persistence using SwiftData. Use when defining @Model classes with @Attribute, @Relationship, @Transient, #Unique, or #Index; when querying with @Query, #Predicate, FetchDescriptor, or SortDescriptor; when configuring ModelContainer and

SKILL.md

swiftdata.SKILL.md
name: swiftdata
description: "Implement, review, or improve data persistence using SwiftData. Use when defining @Model classes with @Attribute, @Relationship, @Transient, #Unique, or #Index; when querying with @Query, #Predicate, FetchDescriptor, or SortDescriptor; when configuring ModelContainer and ModelContext for SwiftUI or background work with @ModelActor; when planning schema migrations with VersionedSchema and SchemaMigrationPlan; when setting up CloudKit sync with ModelConfiguration; or when coexisting with or migrating from Core Data."

SwiftData

Persist, query, and manage structured data in iOS 26+ apps using SwiftData with Swift 6.3.

Contents

  • [Model Definition](#model-definition)
  • [ModelContainer Setup](#modelcontainer-setup)
  • [CloudKit Sync](#cloudkit-sync)
  • [CRUD Operations](#crud-operations)
  • [`@Query in SwiftUI`](#query-in-swiftui)
  • [#Predicate](#predicate)
  • [FetchDescriptor](#fetchdescriptor)
  • [Schema Versioning and Migration](#schema-versioning-and-migration)
  • [Core Data Coexistence Boundary](#core-data-coexistence-boundary)
  • [Concurrency (`@ModelActor`)](#concurrency-modelactor)
  • [SwiftUI Integration](#swiftui-integration)
  • [Common Mistakes](#common-mistakes)
  • [Review Checklist](#review-checklist)
  • [References](#references)

Model Definition

Apply `@Model` to a **class** (not struct). It synthesizes `PersistentModel` conformance. Model instances remain context/actor-bound; pass their `PersistentIdentifier`, not the instance, across actors.

@Model
class Trip {
    var name: String
    var destination: String
    var startDate: Date
    var endDate: Date
    var isFavorite: Bool = false
    @Attribute(.externalStorage) var imageData: Data?
    @Relationship(deleteRule: .cascade, inverse: \LivingAccommodation.trip)
    var accommodation: LivingAccommodation?
    @Transient var isSelected: Bool = false  // Always provide default

    init(name: String, destination: String, startDate: Date, endDate: Date) {
        self.name = name; self.destination = destination
        self.startDate = startDate; self.endDate = endDate
    }
}

**`@Attribute` options**: `.externalStorage`, `.unique`, `.spotlight`, `.allowsCloudEncryption`, `.preserveValueOnDeletion`, `.ephemeral`, `.transformable(by:)`. Rename: `@Attribute(originalName: "old_name")`.

**`@Relationship`**: `deleteRule:` `.cascade`/`.nullify`(default)/`.deny`/`.noAction`. Specify `inverse:` for reliable behavior. Unidirectional (iOS 18+): `inverse: nil`.

**#Unique (iOS 18+)**: `#Unique<Person>([\.firstName, \.lastName])` -- compound uniqueness.

**Inheritance (iOS 26+)**: `@Model class BusinessTrip: Trip { var company: String }`.

Supported types: `Bool`, `Int`/`UInt` variants, `Float`, `Double`, `String`, `Date`, `Data`, `URL`, `UUID`, `Decimal`, `Array`, `Dictionary`, `Set`, `Codable` enums, `Codable` structs and other compatible `Codable` value types, and relationships to `@Model` classes.

ModelContainer Setup

// Basic
let container = try ModelContainer(for: Trip.self, LivingAccommodation.self)

// Configured
let config = ModelConfiguration("Store", isStoredInMemoryOnly: false,
    groupContainer: .identifier("group.com.example.app"),
    cloudKitDatabase: .private("iCloud.com.example.app"))
let container = try ModelContainer(for: Trip.self, configurations: config)

// With migration plan
let container = try ModelContainer(for: SchemaV2.Trip.self,
    migrationPlan: TripMigrationPlan.self)

// In-memory (previews/tests)
let container = try ModelContainer(for: Trip.self,
    configurations: ModelConfiguration(isStoredInMemoryOnly: true))

CloudKit Sync

`ModelConfiguration(..., cloudKitDatabase:)` opts a SwiftData store into automatic CloudKit sync, but app entitlements still gate sync.

For any SwiftData CloudKit setup or schema-review task, include a separate **Capabilities** verdict before schema findings:

  • **Capabilities**: Xcode target has the iCloud capability with CloudKit enabled

and the intended container selected, plus Background Modes > Remote notifications. Without these entitlements, automatic sync is not fully configured even if `cloudKitDatabase` is set.

  • **Schema compatibility**: no `@Attribute(.unique)` or `#Unique`;

relationships are optional, have explicit inverses where needed, and avoid `.deny`; large `Data` uses `@Attribute(.externalStorage)`.

  • **Scalar attributes**: do not make every scalar optional just for CloudKit.

Keep required scalars nonoptional when initializers, defaults, or migrations provide valid values.

  • **Schema rollout**: initialize the development schema only in nonproduction

builds, verify it in CloudKit Dashboard, promote before release, and treat production changes as additive only.

CRUD Operations

For destructive batches and migrations, first run the exact predicate or version hop against a disposable copy and record affected identifiers/counts. Execute with explicit transaction/save semantics, refetch, and verify values, relationships, counts, and invariants. On failure, fix the predicate/schema and restore a pristine fixture before retrying; never blindly replay a destructive operation.

// CREATE
let trip = Trip(name: "Summer", destination: "Paris", startDate: .now, endDate: .now + 86400*7)
modelContext.insert(trip)
try modelContext.save()  // or rely on autosave

// READ
let trips = try modelContext.fetch(FetchDescriptor<Trip>(
    predicate: #Predicate { $0.destination == "Paris" },
    sortBy: [SortDescriptor(\.startDate)]))

// UPDATE -- modify properties directly; autosave handles persistence
trip.destination = "Rome"

// DELETE
modelContext.delete(trip)
try modelContext.delete(model: Trip.self, where: #Predicate { $0.isFavorite == false })

// TRANSACTION (atomic)
try modelContext.transaction {
    modelContext.insert(trip); trip.isFavorite = true
}

`@Query` in SwiftUI

struct TripListView: View {
    @Query(filter: #Predicate<Trip> { $0.isFavorite =
Read more
Ships withswift-ios-skills

86 agent skills optimized for iOS 26+ development with Swift 6.3 and modern Apple frameworks.

Get the whole plugin
Stats
981
Stars
50
Forks
Active
Maintenance
Python
Language
9d ago
Last commit
5mo ago
Created

Repo: dpearson2699/swift-ios-skills

Other skills on swift-ios-skills.