Skip to content

// SwiftData (iOS 17+) the production way — @Model, @Query, CloudKit sync, predicates, migrations.

iOS SwiftData Modern

skill --stat
  • last update

    Jun 2, 2026

  • license

    MITv1.0.0

  • format

    SKILL.md

quickstart.sh
3 steps
  1. Install

    // Downloads SKILL.md into ~/.claude/skills/ios-swiftdata-modern/

    $ curl -fsSL --create-dirs -o ~/.claude/skills/ios-swiftdata-modern/SKILL.md https://claudeskil.com/skills/ios-swiftdata-modern/SKILL.md
  2. Invoke

    // Inside Claude Code, type the skill name as a slash command

    > /ios-swiftdata-modern help me ship this
  3. Or just ask

    // Claude loads the skill by itself when a request matches its description

    > help me ship this
ios-swiftdata-modern/
references
SKILL.md
readonly
name:
iOS SwiftData Modern
slug:
ios-swiftdata-modern
version:
v1.0.0
license:
MIT
author:
@chiragthummar16
categories:
tags:
#swiftdata#swift#ios17#cloudkit#persistence
description:

SwiftData (iOS 17+) the production way — @Model, @Query, CloudKit sync, predicates, migrations.

README.md

ios-swiftdata-modern/README.md
6 sections

iOS SwiftData Modern

A focused skill for building persistence layers with SwiftData, Apple's declarative framework introduced at WWDC23 for iOS 17+. It helps you design @Model schemas, write type-safe #Predicate queries, wire up ModelContainer/ModelContext, enable CloudKit mirroring, and plan schema migrations — without falling back into Core Data ceremony. Aimed at iOS developers starting new apps or moving off NSManagedObject boilerplate.

When to use it

  • You're starting a fresh iOS 17+ (or iOS 18) app and want persistence wired correctly the first time.
  • You need @Query to drive a SwiftUI list with filtering and sorting that stays in sync automatically.
  • You want iCloud sync across a user's devices and aren't sure how automatic CloudKit configuration constrains your model.
  • You have a shipped schema and need to evolve it safely with a SchemaMigrationPlan.
  • You're weighing SwiftData against Core Data and want a clear decision tree rather than vibes.

How it works

The skill scaffolds the real building blocks:

  • Schema — classes annotated with @Model, using @Attribute(.unique), @Attribute(.externalStorage) for blobs, @Relationship(deleteRule: .cascade), and @Transient for non-persisted fields.
  • Container — .modelContainer(for:) on your App scene, or a manually built ModelContainer(for:configurations:) with a ModelConfiguration (including .modelContainer(... isStoredInMemoryOnly:) for tests/previews).
  • Queries — @Query(filter:sort:) with #Predicate and SortDescriptor, plus FetchDescriptor and context.fetch(_:) for imperative reads.
  • Writes — @Environment(\.modelContext), then context.insert(_:), context.delete(_:), and context.save().
  • Sync — a CloudKit-backed ModelConfiguration(cloudKitDatabase:), with the constraints it imposes (no .unique, all properties optional or defaulted, no deleteRule: .deny).
  • Migrations — VersionedSchema types plus a SchemaMigrationPlan with lightweight and .custom migration stages.

Usage example

bash
curl -fsSL --create-dirs -o ~/.claude/skills/ios-swiftdata-modern/SKILL.md https://claudeskil.com/skills/ios-swiftdata-modern/SKILL.md
swift
@Model
final class Trip {
    var name: String
    var startDate: Date
    @Relationship(deleteRule: .cascade) var stops: [Stop] = []
    init(name: String, startDate: Date) { self.name = name; self.startDate = startDate }
}

// In a SwiftUI view
@Query(filter: #Predicate<Trip> { $0.startDate > .now },
       sort: \Trip.startDate) private var upcoming: [Trip]
@Environment(\.modelContext) private var context

Tips & gotchas

  • #Predicate runs against the store, so unsupported operations (many String methods, computed properties) throw at fetch time, not compile time — keep predicates simple.
  • CloudKit mirroring forbids @Attribute(.unique) and requires every property to be optional or have a default; design for that from day one or migration is painful.
  • @Query only refreshes for the context it's attached to — background writes need the same container, and you may need context.save() for cross-context visibility.
  • Use isStoredInMemoryOnly: true configurations in #Preview and unit tests to avoid polluting the on-disk store.

FAQ

Should I pick SwiftData or Core Data? For new iOS 17+ apps, SwiftData unless you need NSFetchedResultsController-level control, fine-grained migration, or pre-iOS-17 support — then Core Data (or both, since they share the store).

Can I run raw fetches outside SwiftUI? Yes — build a FetchDescriptor with a #Predicate and call modelContext.fetch(_:).

Do I get migrations for free? Additive changes are lightweight automatically; renames or type changes need a SchemaMigrationPlan with a custom stage.

$ cat reviews/

Reviews

// No reviews yet. Be the first.
Loading review form…

$ ls related/

explore all →