DevTechie/Mastering SwiftData: The Complete Guide for iOS 27, SwiftUI & Swift 6.4

  • $59.99

Mastering SwiftData: The Complete Guide for iOS 27, SwiftUI & Swift 6.4

  • Course
  • 122 Lessons

A complete, current SwiftData reference for iOS 27 and Swift 6.4 — going far beyond @Model and @Query into concurrency, migrations, CloudKit, performance, architecture, testing, and debugging. Built around one real app, with every claim checked against Apple's own documentation rather than assumed. For developers who know Swift and want genuine, production-level SwiftData proficiency — not just the basics.

Contents

Part 1 — Foundations

What SwiftData is, where it sits relative to Core Data, and the three components — @Model, ModelContainer, ModelContext — that everything else in this book builds on. By the end of this part you’ll understand SwiftData’s mental model well enough to know why the later parts are organized the way they are, and you’ll have a model wired into a SwiftUI view. This part deliberately stays high-level; deep treatment of each component comes later.

What Is SwiftData?
SwiftData vs. Core Data, Today
The Building Blocks: @Model, ModelContainer, ModelContextat a Glance
Designing Your First Model
ModelContainer Explained
ModelContext Explained
SwiftData in a SwiftUI View
Part 1: Knowledge Check

Part 2 - Model Design Deep Dive

Everything that goes into designing a single @Model type correctly: attribute options, optionality, defaults, transient properties, enums, custom value types, the new Codable attribute support, uniqueness constraints, and indexes. This is the part to return to whenever you’re starting a new model and want to get the shape right the first time, before relationships or migrations enter the picture.

Attributes, Optionality, and Default Values
@Attribute Options: Unique Constraints & #Unique
Transient Properties
Enums and Custom Value Types as Attributes
Codable Attributes (iOS 27)
Indexes and Compound Indexes: #Index
Schema Design Principles & Common Mistakes
Part 2: Knowledge Check

Part 3 — Relationships, In Depth

Covers cardinality and inverses, one-to-many and many-to-many relationships built correctly, one-to-one and unidirectional relationships, the four delete rules, optional relationships and the specific nil-handling crashes they can cause, relationship performance and traversal, and the common mistakes — including circular relationships — that show up once a schema has more than one model type. This part treats relationships as a first-class design problem rather than an afterthought to Part 2's single-model focus. By the end you'll know which delete rule to reach for and why, not just what each one does.

Relationship Fundamentals: Cardinality and Inverses
One-to-Many Relationships, Built Right
Many-to-Many Relationships
One-to-One and Unidirectional Relationships
Delete Rules: Cascade, Nullify, Deny
Optional Relationships and Nil-Handling Pitfalls
Relationship Performance and Traversal
Common Relationship Mistakes and Circular Relationships
Part 3 Quiz: Relationships, In Depth

Part 4 — Build a Complete App

Build a Complete App Everything from Parts 1 through 3 applied to a real, working app — the Book Tracker — built from an empty Xcode project through fetching, inserting, updating, and deleting records, a real bug and its non-obvious root cause, a custom view modifier, storing images correctly, and empty states. This is the part where the theory becomes a screen you can actually use, and the app built here is what every later part in this book continues to extend.

Project Setup: Building the Book Tracker App
Fetching Data with @Query
Inserting and Updating Records
Deleting Records
The Number-Formatting Bug (and Why It Still Matters)
A Custom View Modifier for Conditional Sections
Storing Images with SwiftData, Part 1 — @Attribute(.externalStorage)
Storing Images with SwiftData, Part 2 — Loading, Caching, Performance
Empty States with ContentUnavailableView
Book Tracker Source Code
Part 4 Quiz: Build a Complete App

Part 5 - Previews & Mock Data

Previews & Mock Data Building realistic sample data for SwiftUI previews without touching a real device's store, the PreviewModifier protocol for caching that sample data across multiple previews, and @Previewable for genuinely interactive previews without a throwaway wrapper view. Short, but worth its own part: every later chapter's code examples lean on these three techniques without re-explaining them.

Mocking Data for SwiftUI Previews
PreviewModifier
The @Previewable Property Wrapper
Part 5 Quiz: Previews & Mock Data

Part 6: Querying and Fetching

Querying and Fetching The largest part in the book, and the one most developers will return to most often: @Query's actual mechanics, FetchDescriptor for fetches outside a view, writing and combining predicates (including the iOS 27 enum and sectioned-query additions), sorting, filtering strategy (Swift-side vs. store-side), fetch limits and pagination, querying relationships efficiently, animating query results, and querying from outside SwiftUI entirely — widgets, background code. Treat this part as the reference section for "how do I actually get the data I want."

@Query Deep Dive
FetchDescriptor and Fetching from ModelContext
#Predicate: Writing Predicates
Dynamic and Compound Predicates
Enum Predicates (iOS 27)
Sorting: Single and Multiple Sort Descriptors
Filtering Data in SwiftUI vs. in the Query Layer
Advanced Filtering & Sorting Patterns
Fetch Limits and Offsets
Sectioned Queries (iOS 27)
Querying Relationships Efficiently
@Query Animations
Querying Outside SwiftUI
Part 6 Quiz: Querying and Fetching

Part 7: Swift Concurrency and SwiftData

Swift Concurrency and SwiftData The mental model for isolation domains and why ModelContainer is Sendable while ModelContext isn't, ModelContext's main-actor default, ModelActor for genuine background work, Sendability rules for your own types, importing large datasets safely, and the specific pitfalls — including actor reentrancy — that show up once real concurrent access enters the picture. This part exists because getting it wrong produces crashes that only show up under real load, not in a simple demo — worth reading carefully even if your app feels too small to need it yet.

Concurrency Mental Model: Contexts, Actors, and Isolation
ModelContext Isolation and the Main Actor
ModelActor and @ModelActor
Sendability
Performing Background Work: Importing Large Datasets
Concurrency-Related SwiftData Pitfalls
Part 7 Quiz: Swift Concurrency and SwiftData

Part 8: Observation and Change Tracking

Observation and Change Tracking The shift from "what does the data look like right now" (@Query) to "what actually changed, and when" (persistent history): HistoryDescriptor, reading the contents of a transaction, tokens for tracking progress and cleaning up old history, and the two new iOS 27 observation tools — ResultsObserver for @Query-like reactivity outside a view, and HistoryObserver for building an actual sync pipeline. Come back to this part the moment you need to know not just the current state of your data, but the story of how it got there.

From View-Driven Observation to Store-Level Change Tracking
HistoryDescriptor: Fetching and Filtering Transactions
Inside a Transaction: Insert, Update, and Delete
Tokens: Persisting Progress and Cleaning Up History
ResultsObserver (iOS 27)
HistoryObserver (iOS 27) and Building a Sync Pipeline
Part 8 Quiz: Observation and Change Tracking

Part 9 - Migrations

Migrations What SwiftData migrates automatically and the real boundary where that stops — type changes, never — VersionedSchema and SchemaMigrationPlan, custom migrations with willMigrate/didMigrate, migrating relationships specifically, testing a migration against realistic old data, handling a migration that fails in production, backward compatibility for users skipping several versions at once, and data preservation as a last line of defense. Migrations are where a schema decision made in Part 2 either pays off or costs you later — this is the most consequential part in the book for an app that's already shipped.

Schema Evolution: What Counts as a Change?
Automatic Migration in Full Depth
VersionedSchema and SchemaMigrationPlan
Custom Migrations: willMigrate and didMigrate in Practice
Migrating Relationships
Migration Testing with Realistic Existing Stores
Handling Failed Migrations: Production Strategies
Backward Compatibility
Data Preservation: Backups, Exports, and Defense in Depth
Part 9 Quiz: Migrations

Part 10 - CloudKit and iCloud Sync

CloudKit and iCloud Sync CloudKit's complete, non-negotiable schema requirements, reconciling an existing schema to meet them, container configuration and entitlements, how sync and remote changes actually behave, what CloudKit's conflict resolution really does — and doesn't do, debugging sync failures, the real difference between development and production environments, and migration considerations once CloudKit is live. Written to correct a specific, common assumption: enabling CloudKit is not the same as having a sync architecture.

SwiftData + CloudKit: The Mental Model and Schema Requirements
Reconciling the Schema for CloudKit
CloudKit Container Configuration and Entitlements
Sync Behavior, Remote Changes, and Eventual Consistency
Conflict Scenarios: What CloudKit Actually Resolves
Debugging CloudKit Synchronization
Development vs. Production CloudKit Environments
Data Migration Considerations With CloudKit
Part 10 Quiz: CloudKit and iCloud Sync

Part 11 - Custom Data Stores

Custom Data Stores An advanced, narrow part: what DefaultStore actually is, the DataStore protocol's real requirements, and the optional DataStoreBatching and HistoryProviding protocols. Most apps, including this book's own, never need any of this — the part is honest about that up front, and exists for the specific, concrete cases where DefaultStore genuinely isn't enough.

Custom Data Stores: Architecture and When It’s Actually Justified
The DataStore Protocol in Depth
DataStoreBatching and HistoryProviding
Part 11 Quiz: Custom Data Stores

Part 12 - Performance

Performance Measuring correctly before optimizing anything — Instruments, not guesses — fetch and predicate efficiency, when indexing actually helps, memory and faulting behavior, the real cost of background imports on the main thread, and CloudKit-specific performance considerations. Every claim in this part is tied to a specific tool or a specific, documented finding — nothing here is "SwiftData is just slow," everything is "here's how to find out why."

Measuring Performance: Tools Before Guesses
Fetch and Predicate Efficiency
Indexing: What It Solves and When It’s Worth It
Memory Usage, Relationship Traversal, and Faulting
Background Imports and Main-Thread Performance
CloudKit Performance Considerations
Part 12 Quiz: Performance

Part 13 - Architecture

Architecture Where SwiftData fits into a real app's structure: the simple @Query-in-views pattern as a legitimate choice, MVVM done properly — and why it genuinely conflicts with @Query — repositories and service layers, networking and caching, offline-first design, sync architecture beyond CloudKit's own integration, and what changes once an app is genuinely large. No single architecture is prescribed — every chapter argues for introducing structure only when a concrete need justifies it.

Simple SwiftUI + SwiftData: A Legitimate Architecture, Not Just a Starting Point
MVVM With SwiftData, Done Properly
Repository Patterns and Service Layers
Networking and SwiftData Caching
Offline-First Architecture
Sync Architecture: CloudKit’s Automatic Path and Building Your Own
Large Application Architecture
Part 13 Quiz: Architecture

Part 14 - Testing

Testing A complete testing discipline built on in-memory containers: model tests, query tests, relationship tests, migration tests, concurrency tests — and the honest limits of what they can prove — persistence integration tests, and what's actually verifiable about CloudKit sync without a live account. Every test in this part targets your own logic, never SwiftData's own, already-guaranteed mechanics.

In-Memory Containers and Test-Specific Model Containers
Model Tests
Query Tests
Relationship Tests
Migration Tests
Concurrency Tests
Persistence Integration Tests
CloudKit-Related Testing Considerations
Part 14 Quiz: Testing

Part 15 - Debugging

Debugging Practical, pattern-recognition-based debugging for the failures a real SwiftData app eventually produces: schema and relationship errors, predicate and migration failures, CloudKit sync and concurrency problems, unexpected saves and missing updates, and store corruption itself. Built around real, confirmed error messages and documented incidents rather than generic troubleshooting advice — the part to open first when something is actually broken.

Debugging Model Schema and Relationship Errors
Debugging Predicate and Migration Failures
Debugging CloudKit Sync and Concurrency Problems
Unexpected Saves, Missing Updates, and Duplicate Records
Debugging Store Corruption and Invalid Persistent Stores
Closing: What the Book Tracker Became
Part 15 Quiz: Debugging