TechnologiesData, Storage & Cloud

SwiftData

iOSmacOStvOSwatchOSvisionOS

SwiftData is Apple's modern, declarative persistence framework designed to integrate seamlessly with Swift and SwiftUI. It replaces the complex XML mapping files and heavy boilerplate of Core Data with a modern, compile-time type-safe API. You define your schema using standard Swift classes annotated with the `@Model` macro. SwiftData automatically handles relationships, migrations, constraints, and persistence behind the scenes, allowing you to focus on your app's business logic.

The architecture revolves around three main components: models, containers, and contexts. Your models conform to `PersistentModel` via the `@Model` macro. A `ModelContainer` manages the persistent store (usually SQLite on disk) and translates your schema definitions into tables, columns, and relations. To fetch, insert, update, or delete records, you interact with a `ModelContext`, which tracks changes in memory until you save them. This state management integrates directly into SwiftUI, where property wrappers like `@Query` automatically keep your views synchronized with the underlying database.

For advanced database operations, SwiftData provides robust tools for fetching, migration, and concurrency. You query models using `FetchDescriptor`, defining precise search criteria, sort orders, and pre-fetching rules. Schema changes are managed using `VersionedSchema` and `SchemaMigrationPlan`, supporting both automatic lightweight migrations and complex custom stages. For background operations, conforming to the `ModelActor` protocol ensures that database queries are isolated to serial background actors, preventing thread safety violations and main thread blocking.

Get started

Define a model, set up a container, and perform basic CRUD operations

import SwiftData
import Foundation

// Define a persistable Swift class using the @Model macro
@Model
class TodoItem {
    @Attribute(.unique) var id: UUID
    var title: String
    var isCompleted: Bool
    
    init(title: String) {
        self.id = UUID()
        self.title = title
        self.isCompleted = false
    }
}

// Initialize a ModelContainer (holds the schema and SQLite database configuration)
let container = try ModelContainer(for: TodoItem.self)

// Get the main context (typically on the main thread for UI interaction)
let context = container.mainContext

// 1. Create: Insert a new item
let newItem = TodoItem(title: "Buy groceries")
context.insert(newItem)
try context.save() // Commit changes to the persistent store

// 2. Read: Fetch items using a FetchDescriptor
let descriptor = FetchDescriptor<TodoItem>(predicate: #Predicate { !$0.isCompleted })
let openTodos = try context.fetch(descriptor)
assert(openTodos.count == 1)

// 3. Update: Modify properties directly
newItem.isCompleted = true
try context.save() // SwiftData tracks the change and saves automatically

// 4. Delete: Remove the item from the context
context.delete(newItem)
try context.save()

Key concepts

Macro-Driven Schema

By annotating standard Swift classes with `@Model`, the compiler automatically generates conformances to `PersistentModel`. This macro instruments your properties with getter/setter hooks that load data from disk on-demand, handle relationships automatically, and track unsaved modifications.

Contextual Modification Tracking

A `ModelContext` acts as an in-memory scratchpad for your database. As you modify model instances, insert new items, or delete old ones, the context tracks these changes. Calling `save()` pushes these modifications to the database in a single atomic transaction.

Query Integration in SwiftUI

SwiftData is built to power SwiftUI. The `@Query` property wrapper in a view automatically performs fetches and registers the view for updates. When data changes in the underlying store, the view is automatically updated to reflect the new state.

Compiler-Enforced Actor Concurrency

To safely work with databases off the main thread, SwiftData utilizes Swift's actor model. By conforming to `ModelActor`, you create a background worker that has its own isolated `ModelContext` running on a private serial executor, eliminating cross-thread data corruption.

Essentials 6

The core components you need to initialize SwiftData, define persistent model classes, configure target storage locations, and perform basic context operations.

  • Pr
    PersistentModeliOS 17+
    A protocol applied automatically by the `@Model` macro to turn standard Swift classes into persistent objects managed by SwiftData. It provides tracking for changes, relationship resolution, and lazy property loading.
    persistentModelIDmodelContexthasChanges
    @Model class Book {
      var title: String
      init(title: String) { self.title = title }
    }
  • Cl
    ModelContaineriOS 17+
    An object that manages the persistent store and holds the database schemas. It initializes the database at a target file URL and provides model contexts for your app.
    init(for:configurations:)mainContextconfigurationsdeleteAllData()
    let container = try ModelContainer(for: Book.self)
  • Cl
    ModelContextiOS 17+
    An object that serves as the primary workspace for database operations. It tracks inserted, modified, and deleted models, and commits changes to the underlying storage during saving.
    insert(_:)delete(_:)save()fetch(_:)hasChangesundoManager
    let context = container.mainContext
    context.insert(Book(title: "SwiftUI by Example"))
    try context.save()
  • St
    ModelConfigurationiOS 17+
    A value that configures the storage location, group permissions, cloud sync capabilities, and read-only status of a persistent store backing your container.
    urlnameisStoredInMemoryOnlyallowsCloudKitSync
    let config = ModelConfiguration(isStoredInMemoryOnly: true)
    let container = try ModelContainer(for: Book.self, configurations: config)
  • St
    PersistentIdentifieriOS 16+
    A stable, unique identifier referencing a persistent model object across app runs and threads. Safe to pass between model contexts on different actors.
    storeIdentifierentityName
    let bookID = book.persistentModelID
    let safeBook = context.model(for: bookID) as? Book
  • Cl
    SchemaiOS 17+
    An object that maps model classes to data in the model store, and helps with the migration of that data

Fetching Data 5

Types and descriptors used to query the database, filter records with compiler-verified predicates, sort results, and observe collection changes.

  • St
    FetchDescriptoriOS 17+
    A structure describing the search query parameters, sort descriptors, pagination offsets, and pre-fetching rules used to fetch persistent models from a context.
    predicatesortByfetchLimitfetchOffsetpropertiesToFetch
    let descriptor = FetchDescriptor<Book>(
      predicate: #Predicate { $0.title.contains("Swift") }
    )
    let books = try context.fetch(descriptor)
  • St
    FetchResultsCollectioniOS 17+
    A collection that efficiently provides the results of a completed fetch.
  • St
    ResultsSectioniOS 27+
    A section of fetched results grouped by a common section key path value.
  • St
    ResultsSectionCollectioniOS 27+
    A collection of sections as returned by ``ResultsObserver/sections`` or `Query.sections`.
  • Cl
    ResultsObserveriOS 27+
    Observes and tracks changes to a collection of persistent models in a model context.

Schema Definition 3

Protocols and structures that describe how properties are mapped, relationships between models are linked, and how backing data is structured.

  • Pr
    SchemaPropertyiOS 17+
    An interface for describing a property.
  • Pr
    RelationshipCollectioniOS 17+
    A protocol describing a collection of related persistent models in a relationship.
  • Pr
    BackingDataiOS 17+
    An interface for providing in-memory storage for a persistent model.

Schema Migration 3

Classes and plans for versioning your schemas and running migrations to evolve your database safely across app updates.

  • Pr
    VersionedSchemaiOS 17+
    A protocol defining a snapshot of your database schema at a specific version. Used to organize and execute sequential database migrations.
    versionIdentifiermodels
    enum BookSchemaV1: VersionedSchema {
      static var versionIdentifier: Schema.Version = .init(1, 0, 0)
      static var models: [any PersistentModel.Type] = [Book.self]
    }
  • Pr
    SchemaMigrationPlaniOS 17+
    A protocol that describes the sequence of versioned schemas and specifies the stages (lightweight or custom) needed to migrate user data between versions.
    schemasstages
    struct BookMigrationPlan: SchemaMigrationPlan {
      static var schemas: [any VersionedSchema.Type] = [BookSchemaV1.self, BookSchemaV2.self]
      static var stages: [MigrationStage] = [MigrationStage.lightweight(from: BookSchemaV1.self, to: BookSchemaV2.self)]
    }
  • En
    MigrationStageiOS 17+
    An enum describing a lightweight (automatic) or custom (run by code) step inside a schema migration plan to perform data transformations.
    .lightweight(from:to:).custom(from:to:willMigrate:didMigrate:)
    let stage = MigrationStage.custom(from: V1.self, to: V2.self, willMigrate: { context in
      // Run custom SQL or modify data before schema updates
    }, didMigrate: nil)

Concurrency 5

APIs and protocols designed to run database operations safely in the background, isolating context instances using Swift actors.

  • Pr
    ModelActoriOS 17+
    A protocol that isolates database access to a serial background actor, facilitating thread-safe database operations in the background.
    modelContainermodelExecutormodelContext
    actor BackgroundImporter: ModelActor {
      let modelContainer: ModelContainer
      let modelExecutor: any ModelExecutor
      init(container: ModelContainer) {
        self.modelContainer = container
        self.modelExecutor = DefaultSerialModelExecutor(modelContext: ModelContext(container))
      }
    }
  • Pr
    ModelExecutoriOS 17+
    An interface for performing storage-related tasks using an isolated model context.
  • Pr
    SerialModelExecutoriOS 17+
    An interface for performing serial storage-related tasks using an isolated model context.
  • Cl
    DefaultSerialModelExecutoriOS 17+
    An object that safely performs storage-related tasks using an isolated model context.
  • St
    EditingStateiOS 18+
    A value that describes the editing state of a model context's pending changes.

Persistent History 15

APIs for observing and replaying change transactions (inserts, updates, deletes) recorded in the store's persistent history stream.

  • St
    HistoryDescriptoriOS 18+
    A type that defines which persistent history transactions to fetch and how to bound them.
  • Pr
    HistoryProvidingiOS 18+
    A protocol for data stores that vend persistent history transactions.
  • Cl
    HistoryObserveriOS 27+
    Monitors a model container's data stores for remote changes and notifies
  • Pr
    HistoryTokeniOS 18+
    A protocol that represents a position marking how far history has been read.
  • St
    DefaultHistoryTokeniOS 18+
    The built-in token marking a position in the store's persistent history.
  • Pr
    HistoryTransactioniOS 18+
    A protocol that describes a group of changes recorded together in persistent history.
  • St
    DefaultHistoryTransactioniOS 18+
    The built-in type representing a transaction recorded in persistent history.
  • En
    HistoryChangeiOS 18+
    An enumeration of the kinds of change—insert, update, or delete—recorded in persistent history.
  • Pr
    HistoryInsertiOS 18+
    A protocol that describes an insertion recorded in the store's persistent history.
  • St
    DefaultHistoryInsertiOS 18+
    The built-in type representing an insertion recorded in persistent history.
  • Pr
    HistoryUpdateiOS 18+
    A protocol that describes an update recorded in the store's persistent history.
  • St
    DefaultHistoryUpdateiOS 18+
    The built-in type representing an update recorded in persistent history.
  • Pr
    HistoryDeleteiOS 18+
    A protocol that describes a deletion recorded in the store's persistent history.
  • St
    DefaultHistoryDeleteiOS 18+
    The built-in type representing a deletion recorded in persistent history.
  • St
    HistoryTombstoneiOS 18+
    A record that preserves selected values of a model that was deleted from the store.

Custom Data Stores 12

Protocols and types that allow you to implement custom persistence backends, swapping SQLite out for your own custom file format or server API.

  • Pr
    DataStoreiOS 18+
    A protocol you adopt to implement a custom backing store for SwiftData models.
  • Cl
    DefaultStoreiOS 18+
    The built-in data store that persists SwiftData models on Core Data.
  • Pr
    DataStoreConfigurationiOS 18+
    A protocol that describes the configuration of a custom data store.
  • Pr
    DataStoreBatchingiOS 18+
    A protocol that adds batch-operation support, such as batch deletes, to a custom data store.
  • Pr
    DataStoreSnapshotiOS 18+
    A protocol that represents a point-in-time copy of a model's values in a custom store.
  • St
    DefaultSnapshotiOS 18+
    The built-in snapshot type capturing a model's values at a point in time.
  • En
    DataStoreSnapshotCodingKeyiOS 18+
    Coding keys used to encode and decode a custom data store's snapshots.
  • St
    DataStoreFetchRequestiOS 18+
    A request that asks a custom data store to fetch models matching a descriptor.
  • St
    DataStoreFetchResultiOS 18+
    The result returned by a custom data store for a fetch request.
  • St
    DataStoreSaveChangesRequestiOS 18+
    A request that asks a custom data store to persist inserted, updated, and deleted models.
  • Cl
    DataStoreSaveChangesResultiOS 18+
    An object that reports the outcome of saving pending changes to a custom data store.
  • St
    DataStoreBatchDeleteRequestiOS 18+
    A request that asks a custom data store to delete models matching a predicate in bulk.

Document-Based Storage 1

Types that integrate SwiftData persistence with Apple's standard document-based file structures and system file pickers.

  • St
    ModelDocument
    A document type that uses SwiftData to manage its storage.

Errors 2

Errors thrown by SwiftData operations when database loading, saving, validation, or schema migration steps fail.

  • St
    SwiftDataErroriOS 17+
    A type that describes a SwiftData error.
  • En
    DataStoreErroriOS 18+
    An error thrown by a custom data store while fulfilling a request.

Structures 1

  • St
    QueryiOS 17.0+
    A property wrapper that fetches a set of models and keeps those models in sync with the underlying

Type Aliases 1

  • Ty
    DataStoreSnapshotValue

Extends 10

ArrayOptionalNSManagedObjectModelEnvironmentValuesSceneViewSceneStorageAppStorageNewDocumentActionDocumentGroup
← Data, Storage & Cloud