
Swiftdata
Implement or refactor SwiftData models, queries, migrations, and CloudKit sync correctly on modern Swift and SwiftUI apps.
Install
npx skills add https://github.com/dpearson2699/swift-ios-skills --skill swiftdataWhat is this skill?
- @Model classes with @Attribute, @Relationship, @Transient, @Unique, and @Index
- @Query, #Predicate, FetchDescriptor, and SortDescriptor query patterns
- ModelContainer and ModelContext setup for SwiftUI and background @ModelActor work
- VersionedSchema and SchemaMigrationPlan for schema evolution
- CloudKit sync via ModelConfiguration and Core Data coexistence or migration paths
Adoption & trust: 1.8k installs on skills.sh; 713 GitHub stars; 3/3 security scanners passed (skills.sh audits).
Recommended Skills
Vercel React Native Skillsvercel-labs/agent-skills
Firebase Basicsfirebase/agent-skills
Building Native Uiexpo/skills
Firebase Ai Logic Basicsfirebase/agent-skills
Native Data Fetchingexpo/skills
Firebase Firestorefirebase/agent-skills
Journey fit
Common Questions / FAQ
Is Swiftdata safe to install?
skills.sh reports 3 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.
SKILL.md
READMESKILL.md - Swiftdata
# 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) - [CRUD Operations](#crud-operations) - [`@Query in SwiftUI`](#query-in-swiftui) - [#Predicate](#predicate) - [FetchDescriptor](#fetchdescriptor) - [Schema Versioning and Migration](#schema-versioning-and-migration) - [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). Generates `PersistentModel`, `Observable`, `Sendable`. ```swift @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` (iOS 18+), `.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 (composite, iOS 18+), relationships to `@Model` classes. ## ModelContainer Setup ```swift // 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)) ``` ## CRUD Operations ```swift // 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.isFavori