axiom-swiftdata

1
1
Source

Use when working with SwiftData - @Model definitions, @Query in SwiftUI, @Relationship macros, ModelContext patterns, CloudKit integration, iOS 26+ features, and Swift 6 concurrency with @MainActor — Apple's native persistence framework

Install

mkdir -p .claude/skills/axiom-swiftdata && curl -L -o skill.zip "https://mcp.directory/api/skills/download/7379" && unzip -o skill.zip -d .claude/skills/axiom-swiftdata && rm skill.zip

Installs to .claude/skills/axiom-swiftdata

About this skill

SwiftData

Overview

Apple's native persistence framework using @Model classes and declarative queries. Built on Core Data, designed for SwiftUI.

Core principle Reference types (class) + @Model macro + declarative @Query for reactive SwiftUI integration.

Requires iOS 17+, Swift 5.9+ Target iOS 26+ (this skill focuses on latest features) License Proprietary (Apple)

When to Use SwiftData

Choose SwiftData when you need

  • ✅ Native Apple integration with SwiftUI
  • ✅ Simple CRUD operations
  • ✅ Automatic UI updates with @Query
  • ✅ CloudKit sync (iOS 17+)
  • ✅ Reference types (classes) with relationships

Use SQLiteData instead when

  • Need value types (structs)
  • CloudKit record sharing (not just sync)
  • Large datasets (50k+ records) with specific performance needs

Use GRDB when

  • Complex raw SQL required
  • Fine-grained migration control needed

For migrations See the axiom-swiftdata-migration skill for custom schema migrations with VersionedSchema and SchemaMigrationPlan. For migration debugging, see axiom-swiftdata-migration-diag.

Example Prompts

These are real questions developers ask that this skill is designed to answer:

Basic Operations

1. "I have a notes app with folders. I need to filter notes by folder and sort by last modified. How do I set up the @Query?"

→ The skill shows how to use @Query with predicates, sorting, and automatic view updates

2. "When a user deletes a task list, all tasks should auto-delete too. How do I set up the relationship?"

→ The skill explains @Relationship with deleteRule: .cascade and inverse relationships

3. "I have a relationship between User → Messages → Attachments. How do I prevent orphaned data when deleting?"

→ The skill shows cascading deletes, inverse relationships, and safe deletion patterns

CloudKit & Sync

4. "My chat app syncs messages to other devices via CloudKit. Sometimes messages conflict. How do I handle sync conflicts?"

→ The skill covers CloudKit integration, conflict resolution strategies (last-write-wins, custom resolution), and sync patterns

5. "I'm adding CloudKit sync to my app, but I get 'Property must have a default value' error. What's wrong?"

→ The skill explains CloudKit constraints: all properties must be optional or have defaults, explains why (network timing), and shows fixes

6. "I want to show users when their data is syncing to iCloud and what happens when they're offline."

→ The skill shows monitoring sync status with notifications, detecting network connectivity, and offline-aware UI patterns

7. "I need to share a playlist with other users. How do I implement CloudKit record sharing?"

→ The skill covers CloudKit record sharing patterns (iOS 26+) with owner/permission tracking and sharing metadata

Performance & Optimization

8. "I need to query 50,000 messages but only display 20 at a time. How do I paginate efficiently?"

→ The skill covers performance patterns, batch fetching, limiting queries, and preventing memory bloat with chunked imports

9. "My app loads 100 tasks with relationships, and displaying them is slow. I think it's N+1 queries."

→ The skill shows how to identify N+1 problems without prefetching, provides prefetching pattern, and shows 100x performance improvement

10. "I'm importing 1 million records from an API. What's the best way to batch them without running out of memory?"

→ The skill shows chunk-based importing with periodic saves, memory cleanup patterns, and batch operation optimization

11. "Which properties should I add indexes to? I'm worried about over-indexing slowing down writes."

→ The skill explains index optimization patterns: when to index (frequently filtered/sorted properties), when to avoid (rarely used, frequently changing), maintenance costs

Migration from Legacy Frameworks

12. "We're migrating from Realm/Core Data to SwiftData"

→ See the comparison table in Migration section below, then follow realm-to-swiftdata-migration or axiom-swiftdata-migration for detailed guides


@Model Definitions

Basic Model

import SwiftData

@Model
final class Track {
    @Attribute(.unique) var id: String
    var title: String
    var artist: String
    var duration: TimeInterval
    var genre: String?

    init(id: String, title: String, artist: String, duration: TimeInterval, genre: String? = nil) {
        self.id = id
        self.title = title
        self.artist = artist
        self.duration = duration
        self.genre = genre
    }
}

Key patterns

  • Use final class, not struct (omit final if you need subclasses — see Class Inheritance below)
  • Use @Attribute(.unique) for primary key-like behavior
  • Provide explicit init (SwiftData doesn't synthesize)
  • Optional properties (String?) are nullable
  • Use @Attribute(.preserveValueOnDeletion) on properties whose values should survive even after the object is deleted (useful for analytics, audit trails)

Relationships

@Model
final class Track {
    @Attribute(.unique) var id: String
    var title: String

    @Relationship(deleteRule: .cascade, inverse: \Album.tracks)
    var album: Album?

    init(id: String, title: String, album: Album? = nil) {
        self.id = id
        self.title = title
        self.album = album
    }
}

@Model
final class Album {
    @Attribute(.unique) var id: String
    var title: String

    @Relationship(deleteRule: .cascade)
    var tracks: [Track] = []

    init(id: String, title: String) {
        self.id = id
        self.title = title
    }
}

Many-to-Many Self-Referential Relationships

@MainActor  // Required for Swift 6 strict concurrency
@Model
final class User {
    @Attribute(.unique) var id: String
    var name: String

    // Users following this user (inverse relationship)
    @Relationship(deleteRule: .nullify, inverse: \User.following)
    var followers: [User] = []

    // Users this user is following
    @Relationship(deleteRule: .nullify)
    var following: [User] = []

    init(id: String, name: String) {
        self.id = id
        self.name = name
    }
}

CRITICAL: SwiftData automatically manages BOTH sides when you modify ONE side.

Correct — Only modify ONE side

// user1 follows user2 (modifying ONE side)
user1.following.append(user2)
try modelContext.save()

// SwiftData AUTOMATICALLY updates user2.followers
// Don't manually append to both sides - causes duplicates!

Wrong — Don't manually update both sides

user1.following.append(user2)
user2.followers.append(user1)  // Redundant! Creates duplicates in CloudKit sync

Unfollowing (remove from ONE side only)

user1.following.removeAll { $0.id == user2.id }
try modelContext.save()
// user2.followers automatically updated

Verifying relationship integrity (for debugging)

// Check if relationship is truly bidirectional
let user1FollowsUser2 = user1.following.contains { $0.id == user2.id }
let user2FollowedByUser1 = user2.followers.contains { $0.id == user1.id }

// These MUST always match after save()
assert(user1FollowsUser2 == user2FollowedByUser1, "Relationship corrupted!")

CloudKit Sync Recovery (if relationships become corrupted)

// If CloudKit sync creates duplicate/orphaned relationships:

// 1. Backup current state
let backup = user.following.map { $0.id }

// 2. Clear relationships
user.following.removeAll()
user.followers.removeAll()
try modelContext.save()

// 3. Rebuild from source of truth (e.g., API)
for followingId in backup {
    if let followingUser = fetchUser(id: followingId) {
        user.following.append(followingUser)
    }
}
try modelContext.save()

// 4. Force CloudKit resync (in ModelConfiguration)
// Re-create ModelContainer to force full sync after corruption recovery

Delete rules

  • .cascade - Delete related objects
  • .nullify - Set relationship to nil
  • .deny - Prevent deletion if relationship exists
  • .noAction - Leave relationship as-is (careful!)

Class Inheritance

SwiftData supports class inheritance for hierarchical models. Use when you have a clear IS-A relationship (e.g., BusinessTrip IS-A Trip) and need both broad queries (all trips) and type-specific queries.

Base and Subclass Pattern

Apply @Model to both base class and subclasses. Omit final on the base class.

@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
    }
}

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

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

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

Type-Based Queries with #Predicate

Query all base class instances (includes subclasses), or filter by type:

// All trips (includes BusinessTrip, PersonalTrip, etc.)
@Query(sort: \Trip.startDate) var allTrips: [Trip]

// Only business trips — use `is` in #Predicate
@Query(filter: #Predicate<Trip> { $0 is BusinessTrip }) var businessTrips: [Trip]

// Filter on subclass-specific properties — use `as?` cast
let vacationPredicate = #Predicate<Trip> {
    if let personal = $0 as? PersonalTrip {
        return personal

---

*Content truncated.*

axiom-swiftui-nav-diag

CharlesWiltgen

Use when debugging navigation not responding, unexpected pops, deep links showing wrong screen, state lost on tab switch or background, crashes in navigationDestination, or any SwiftUI navigation failure - systematic diagnostics with production crisis defense

21

axiom-ios-build

CharlesWiltgen

Use when ANY iOS build fails, test crashes, Xcode misbehaves, or environment issue occurs before debugging code. Covers build failures, compilation errors, dependency conflicts, simulator problems, environment-first diagnostics.

151

axiom-ios-vision

CharlesWiltgen

Use when implementing ANY computer vision feature - image analysis, object detection, pose detection, person segmentation, subject lifting, hand/body pose tracking.

21

axiom-haptics

CharlesWiltgen

Use when implementing haptic feedback, Core Haptics patterns, audio-haptic synchronization, or debugging haptic issues - covers UIFeedbackGenerator, CHHapticEngine, AHAP patterns, and Apple's Causality-Harmony-Utility design principles from WWDC 2021

20

axiom-in-app-purchases

CharlesWiltgen

Use when implementing in-app purchases, StoreKit 2, subscriptions, or transaction handling - testing-first workflow with .storekit configuration, StoreManager architecture, transaction verification, subscription management, and restore purchases for consumables, non-consumables, and auto-renewable subscriptions

10

axiom-cloudkit-ref

CharlesWiltgen

Use when implementing 'CloudKit sync', 'CKSyncEngine', 'CKRecord', 'CKDatabase', 'SwiftData CloudKit', 'shared database', 'public database', 'CloudKit zones', 'conflict resolution' - comprehensive CloudKit database APIs and modern sync patterns reference

00

You might also like

flutter-development

aj-geddes

Build beautiful cross-platform mobile apps with Flutter and Dart. Covers widgets, state management with Provider/BLoC, navigation, API integration, and material design.

9521,094

drawio-diagrams-enhanced

jgtolentino

Create professional draw.io (diagrams.net) diagrams in XML format (.drawio files) with integrated PMP/PMBOK methodologies, extensive visual asset libraries, and industry-standard professional templates. Use this skill when users ask to create flowcharts, swimlane diagrams, cross-functional flowcharts, org charts, network diagrams, UML diagrams, BPMN, project management diagrams (WBS, Gantt, PERT, RACI), risk matrices, stakeholder maps, or any other visual diagram in draw.io format. This skill includes access to custom shape libraries for icons, clipart, and professional symbols.

846846

ui-ux-pro-max

nextlevelbuilder

"UI/UX design intelligence. 50 styles, 21 palettes, 50 font pairings, 20 charts, 8 stacks (React, Next.js, Vue, Svelte, SwiftUI, React Native, Flutter, Tailwind). Actions: plan, build, create, design, implement, review, fix, improve, optimize, enhance, refactor, check UI/UX code. Projects: website, landing page, dashboard, admin panel, e-commerce, SaaS, portfolio, blog, mobile app, .html, .tsx, .vue, .svelte. Elements: button, modal, navbar, sidebar, card, table, form, chart. Styles: glassmorphism, claymorphism, minimalism, brutalism, neumorphism, bento grid, dark mode, responsive, skeuomorphism, flat design. Topics: color palette, accessibility, animation, layout, typography, font pairing, spacing, hover, shadow, gradient."

571699

godot

bfollington

This skill should be used when working on Godot Engine projects. It provides specialized knowledge of Godot's file formats (.gd, .tscn, .tres), architecture patterns (component-based, signal-driven, resource-based), common pitfalls, validation tools, code templates, and CLI workflows. The `godot` command is available for running the game, validating scripts, importing resources, and exporting builds. Use this skill for tasks involving Godot game development, debugging scene/resource files, implementing game systems, or creating new Godot components.

548492

nano-banana-pro

garg-aayush

Generate and edit images using Google's Nano Banana Pro (Gemini 3 Pro Image) API. Use when the user asks to generate, create, edit, modify, change, alter, or update images. Also use when user references an existing image file and asks to modify it in any way (e.g., "modify this image", "change the background", "replace X with Y"). Supports both text-to-image generation and image-to-image editing with configurable resolution (1K default, 2K, or 4K for high resolution). DO NOT read the image file first - use this skill directly with the --input-image parameter.

673466

fastapi-templates

wshobson

Create production-ready FastAPI projects with async patterns, dependency injection, and comprehensive error handling. Use when building new FastAPI applications or setting up backend API projects.

514280

Stay ahead of the MCP ecosystem

Get weekly updates on new skills and servers.