makgunay/claude-swift-skills

swiftdata

SwiftData persistence framework patterns for macOS and iOS apps. Covers @Model definitions, @Query, relationships (with delete rules), ModelContainer/ModelContext configuration, class inheritance with @Model subclasses, type-based predicates (#Predicate with is/as? casting), polymorphic relationships, @Attribute options (.preserveValueOnDeletion), schema migrations, and import/export. Use when implementing data persistence, defining models, querying data, or working with SwiftData. Prevents com…

First seen Feb 14, 2026

Installation

$ npx skills add makgunay/claude-swift-skills --skill swiftdata

Summary

  • SwiftData persistence framework patterns for macOS and iOS apps.
  • Covers @Model definitions, @Query, relationships (with delete rules), ModelContainer/ModelContext configuration, class inheritance with @Model subclasses, type-based predicates (#Predicate with is/as? casting), polymorphic relationships, @Attribute options (.preserveValueOnDeletion), schema migrations, and import/export.
  • Use when implementing data persistence, defining models, querying data, or working with SwiftData.
  • Prevents common LLM errors like generating Core Data syntax, inventing nonexistent SwiftData APIs, or misusing @Query.

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from makgunay/claude-swift-skills · top by installs.

npx skills add makgunay/claude-swift-skills

Browse all from makgunay/claude-swift-skills

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Repository health

Stars 1
License LICENSE
Default branch main
Open issues 0
Status Active

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 5,669 B
  • docs SUMMARY.md 622 B

History

  1. First seen on skills.sh
  2. First recorded snapshot · 12 installs

SKILL.md

SwiftData Persistence Patterns

Critical Constraints

  • ❌ DO NOT use Core Data syntax (NSManagedObject, NSFetchRequest, NSPredicate) → ✅ Use @Model, @Query, #Predicate
  • ❌ DO NOT use @FetchRequest → ✅ Use @Query
  • ❌ DO NOT use string-based predicates → ✅ Use #Predicate<ModelType> macro with Swift expressions
  • ❌ DO NOT create NSPersistentContainer → ✅ Use ModelContainer and ModelContext
  • ❌ DO NOT forget @Model on subclasses → ✅ Both base class AND subclasses need @Model
  • ❌ DO NOT use @Model on structs → ✅ @Model is for classes only

Basic Model Definition

import SwiftData

@Model
class Trip {
    @Attribute(.preserveValueOnDeletion)
    var name: String
    var destination: String
    var startDate: Date
    var endDate: Date

    @Relationship(deleteRule: .cascade, inverse: \Accommodation.trip)
    var accommodation: Accommodation?

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

Class Inheritance

Both base and subclass need @Model. Subclass adds specialized properties.

@Model
class BusinessTrip: Trip {
    var purpose: String
    var expenseCode: String
    var perDiemRate: Double

    @Relationship(deleteRule: .cascade, inverse: \BusinessMeal.trip)
    var businessMeals: [BusinessMeal] = []

    init(name: String, destination: String, startDate: Date, endDate: Date,
         purpose: String, expenseCode: String, perDiemRate: Double) {
        self.purpose = purpose
        self.expenseCode = expenseCode
        self.perDiemRate = perDiemRate
        super.init(name: name, destination: destination, startDate: startDate, endDate: endDate)
    }
}

@Model
class PersonalTrip: Trip {
    enum Reason: String, CaseIterable, Codable, Identifiable {
        case family, vacation, wellness, other
        var id: Self { self }
    }
    var reason: Reason
    var notes: String?

    init(name: String, destination: String, startDate: Date, endDate: Date,
         reason: Reason, notes: String? = nil) {
        self.reason = reason
        self.notes = notes
        super.init(name: name, destination: destination, startDate: startDate, endDate: endDate)
    }
}

Querying with Inheritance

// All trips (base + all subclasses)
@Query(sort: \Trip.startDate) var allTrips: [Trip]

// Filter by subclass type
let businessOnly = #Predicate<Trip> { $0 is BusinessTrip }
@Query(filter: businessOnly) var businessTrips: [Trip]

// Filter by subclass property
let vacations = #Predicate<Trip> {
    if let personal = $0 as? PersonalTrip {
        return personal.reason == .vacation
    }
    return false
}

ModelContainer Setup

@main
struct MyApp: App {
    var body: some Scene {
        WindowGroup { ContentView() }
            .modelContainer(for: [Trip.self, BusinessTrip.self, PersonalTrip.self])
    }
}

// Custom configuration
let config = ModelConfiguration("MyStore", isStoredInMemoryOnly: false)
let container = try ModelContainer(for: Trip.self, configurations: config)

CRUD Operations

// Create
let trip = Trip(name: "Paris", destination: "France", startDate: .now, endDate: .now)
modelContext.insert(trip)

// Read
let descriptor = FetchDescriptor<Trip>(sortBy: [SortDescriptor(\.startDate)])
let trips = try modelContext.fetch(descriptor)

// Update — just modify properties, SwiftData auto-saves
trip.name = "Paris 2025"

// Delete
modelContext.delete(trip)

// Save explicitly
try modelContext.save()

Decision Tree: Inheritance vs Enum

Use inheritance when:
├── Clear IS-A relationship (BusinessTrip IS-A Trip)
├── Subclasses have significantly different properties
├── Need both deep queries (all trips) and shallow queries (business only)
└── Polymorphic relationships needed

Use enum/flag instead when:
├── Only a few shared properties
├── Distinction is simple (just a type tag)
├── Boolean flag suffices
└── Query strategy only focuses on specialized properties

Common Mistakes & Fixes

Mistake Fix
@Model struct MyData @Model class MyData — must be class
NSPredicate(format:) #Predicate<MyModel> { $0.name == "test" }
Missing @Model on subclass Add @Model to both base and subclass
@FetchRequest in SwiftUI @Query var items: [Item]
Forgetting inverse on relationship Add inverse: \OtherModel.property
Not registering subclasses in container Include all model types in .modelContainer(for:)

References