<!--
{
  "availability" : [
    "iOS: 17.0.0 -",
    "iPadOS: 17.0.0 -",
    "macCatalyst: 17.0.0 -",
    "macOS: 14.0.0 -",
    "swift: 5.9.0 -",
    "tvOS: 17.0.0 -",
    "visionOS: 1.0.0 -",
    "watchOS: 10.0.0 -"
  ],
  "documentType" : "symbol",
  "framework" : "SwiftData",
  "identifier" : "/documentation/SwiftData/ModelContext",
  "metadataVersion" : "0.1.0",
  "role" : "Class",
  "symbol" : {
    "kind" : "Class",
    "modules" : [
      "SwiftData"
    ],
    "preciseIdentifier" : "s:9SwiftData12ModelContextC"
  },
  "title" : "ModelContext"
}
-->

# ModelContext

An object that enables you to fetch, insert, and delete models, and save any
changes to disk.

```
class ModelContext
```

## Overview

A model context is central to SwiftData as it’s responsible for managing the
entire lifecycle of your persistent models. You use a context to insert new
models, track and persist changes to those models, and to delete those models
when you no longer need them. A context understands your app’s schema but
doesn’t know about any individual models until you tell it to fetch some from
the persistent storage or populate it with new models. Afterwards, any changes
made to those models exist only in memory until the context implicitly writes
them to the persistent storage, or you manually invoke [`save()`](/documentation/SwiftData/ModelContext/save()). For more
information about implicit writes, see [`autosaveEnabled`](/documentation/SwiftData/ModelContext/autosaveEnabled).

If your app’s schema describes relationships between models, you don’t need to
manually insert each model into the context when you first create them.
Instead, create the graph of related models and insert only the graph’s root
model into the context. The context recognizes the hierarchy and automatically
handles the insertion of the related models. The same behavior applies even if
the graph contains both new and existing models.

A model context depends on a model container for knowledge about your app’s
schema and persistent storage. After you attach a container to your app’s
window group or view hierarchy, an associated context becomes available in the
SwiftUI environment. This context is bound to the main actor and the framework
configures the context to implicitly save future model changes. The
[`Query()`](/documentation/SwiftData/Query()) macros use the same context to perform their fetches.

```swift
struct LastModifiedView: View {
    @Environment(\.modelContext) private var modelContext

}
```

> Important: If you don’t explicitly attach a model container, the environment
> provides a context bound to an in-memory, schema-less container. Any attempt
> to insert a model into this context causes the framework to throw an error, and
> any fetches you run will return empty results.

After you establish access to a model context, use that context’s
[`insert(_:)`](/documentation/SwiftData/ModelContext/insert(_:)) and [`delete(_:)`](/documentation/SwiftData/ModelContext/delete(_:)) methods to add and remove models. You can
also delete several models at once using
[`delete(model:where:includeSubclasses:)`](/documentation/SwiftData/ModelContext/delete(model:where:includeSubclasses:)). There isn’t a corresponding method
to update a model because the context automatically tracks all changes to its
known models. Use the [`hasChanges`](/documentation/SwiftData/ModelContext/hasChanges) property to determine if the context has
unsaved changes, and call [`rollback()`](/documentation/SwiftData/ModelContext/rollback()) to discard any pending inserts and
deletes and any restore changed models to their most recent saved state.

Although you fetch models primarily with the `Query()` macro (and its
variants), you can use a model context to perform almost identical fetches. For
example, use the [`fetch(_:)`](/documentation/SwiftData/ModelContext/fetch(_:)) and [`fetch(_:batchSize:)`](/documentation/SwiftData/ModelContext/fetch(_:batchSize:)) methods to retrieve
all models of a certain type that match a set of criteria. And use
[`fetchCount(_:)`](/documentation/SwiftData/ModelContext/fetchCount(_:)) to determine the number of models that match some criteria
without the overhead of fetching the models themselves. If you need to be able
to identify models that match some criteria but don’t require all of the
associated data, use [`fetchIdentifiers(_:)`](/documentation/SwiftData/ModelContext/fetchIdentifiers(_:)) and [`fetchIdentifiers(_:batchSize:)`](/documentation/SwiftData/ModelContext/fetchIdentifiers(_:batchSize:))
to retrieve only those models’ persistent identifiers.

A model context posts a [`willSave`](/documentation/SwiftData/ModelContext/willSave) notification before it attempts a save
operation, and a [`didSave`](/documentation/SwiftData/ModelContext/didSave) notification immediately after that operation
succeeds. Subscribe to one, or both, of these notifications if your app needs
to be aware of these events. The `didSave` notification provides additional
information about any inserted, updated, and deleted models.

```swift
struct LastModifiedView: View {
    @Environment(\.modelContext) private var context
    @State private var lastModified = Date.now
    
    private var didSavePublisher: NotificationCenter.Publisher {
        NotificationCenter.default
            .publisher(for: ModelContext.willSave, object: context)
    }
    
    var body: some View {
        Text(lastModified.formatted(date: .abbreviated, time: .shortened))
            .onReceive(didSavePublisher) { _ in
                lastModified = Date.now
            }
    }
}
```

> Note: To avoid receiving unwanted or unexpected notifications, always specify
> the model context as the `object` parameter when creating a publisher.

## Topics

### Creating a model context

[`init(_:)`](/documentation/SwiftData/ModelContext/init(_:))

Creates a context that belongs to the specified model container.

[`ModelContainer`](/documentation/SwiftData/ModelContainer)

An object that manages an app’s schema and model storage configuration.

### Fetching models

[`fetch(_:)`](/documentation/SwiftData/ModelContext/fetch(_:))

Returns an array of typed models that match the criteria of the specified fetch
descriptor.

[`fetch(_:batchSize:)`](/documentation/SwiftData/ModelContext/fetch(_:batchSize:))

Returns a collection of typed models, in batches, which match the criteria of
the specified fetch descriptor.

[`fetchCount(_:)`](/documentation/SwiftData/ModelContext/fetchCount(_:))

Returns the number of models that match the criteria of the specified fetch
descriptor.

[`FetchDescriptor`](/documentation/SwiftData/FetchDescriptor)

A type that describes the criteria, sort order, and any additional
configuration to use when performing a fetch.

[`FetchResultsCollection`](/documentation/SwiftData/FetchResultsCollection)

A collection that efficiently provides the results of a completed fetch.

[`enumerate(_:batchSize:allowEscapingMutations:block:)`](/documentation/SwiftData/ModelContext/enumerate(_:batchSize:allowEscapingMutations:block:))

Runs a closure for each model that matches the criteria of the specified fetch
descriptor.

[`model(for:)`](/documentation/SwiftData/ModelContext/model(for:))

Returns the persistent model for the specified identifier.

[`registeredModel(for:)`](/documentation/SwiftData/ModelContext/registeredModel(for:))

Returns the typed model for the specified identifier.

### Inserting models

[`insertedModelsArray`](/documentation/SwiftData/ModelContext/insertedModelsArray)

The array of inserted models that the context is yet to persist.

[`insert(_:)`](/documentation/SwiftData/ModelContext/insert(_:))

Registers the specified model with the context so it can include the model in
the next save operation.

### Modifying models

[`hasChanges`](/documentation/SwiftData/ModelContext/hasChanges)

A Boolean value that indicates whether the context has unsaved changes.

[`changedModelsArray`](/documentation/SwiftData/ModelContext/changedModelsArray)

The array of registered models that have unsaved changes.

### Deleting models

[`deletedModelsArray`](/documentation/SwiftData/ModelContext/deletedModelsArray)

The array of registered models that the context will remove from the persistent
storage during the next save operation.

[`delete(_:)`](/documentation/SwiftData/ModelContext/delete(_:))

Removes the specified model from the persistent storage during the next save
operation.

[`delete(model:where:includeSubclasses:)`](/documentation/SwiftData/ModelContext/delete(model:where:includeSubclasses:))

Removes each model satisfying the given predicate from the persistent storage
during the next save operation.

### Persisting unsaved changes

[`autosaveEnabled`](/documentation/SwiftData/ModelContext/autosaveEnabled)

A Boolean value that indicates whether the context should automatically save
any pending changes when certain events occur.

[`save()`](/documentation/SwiftData/ModelContext/save())

Writes any pending inserts, changes, and deletes to the persistent storage.

[`transaction(block:)`](/documentation/SwiftData/ModelContext/transaction(block:))

Runs the provided closure, and once it finishes, writes any pending inserts,
changes, and deletes to the persistent storage.

[`rollback()`](/documentation/SwiftData/ModelContext/rollback())

Discards pending inserts and deletes, restores changed models to their most
recent committed state, and empties the undo stack.

### Fetching only persistent identifiers

[`fetchIdentifiers(_:)`](/documentation/SwiftData/ModelContext/fetchIdentifiers(_:))

Returns an array of persistent identifiers, where each identifier represents a
single model that satisfies the criteria of the specified fetch descriptor.

[`fetchIdentifiers(_:batchSize:)`](/documentation/SwiftData/ModelContext/fetchIdentifiers(_:batchSize:))

Returns a collection of persistent identifiers, in batches, where each
identifier represents a single model that satisfies the criteria of the
specified fetch descriptor.

### Accessing the container

[`container`](/documentation/SwiftData/ModelContext/container)

The context’s model container.

### Performing undo and redo

[`processPendingChanges()`](/documentation/SwiftData/ModelContext/processPendingChanges())

Tells the undo manager to record any changes made to the context’s registered
models.

[`undoManager`](/documentation/SwiftData/ModelContext/undoManager)

The object that provides undo support for the context.

### Registering for notifications

[`willSave`](/documentation/SwiftData/ModelContext/willSave)

A notification that posts when the context is about to process pending inserts,
changes, and deletes.

[`didSave`](/documentation/SwiftData/ModelContext/didSave)

A notification that posts when the context finishes processing pending inserts,
changes, and deletes.

[`ModelContext.NotificationKey`](/documentation/SwiftData/ModelContext/NotificationKey)

Describes the data in the user info dictionary of a notification sent by a model context.

### Comparing contexts

### Debugging contexts

[`debugDescription`](/documentation/SwiftData/ModelContext/debugDescription)

A textual representation of the context, suitable for debugging.



---

Copyright &copy; 2026 Apple Inc. All rights reserved. | [Terms of Use](https://www.apple.com/legal/internet-services/terms/site.html) | [Privacy Policy](https://www.apple.com/privacy/privacy-policy)