Using SwiftData in SwiftUI Previews
tl;dr:A simple way to create an in-memory SwiftData container with sample data for SwiftUI previews.
When building a SwiftUI app with SwiftData, previews often need a ModelContainer populated with sample data.
Instead of creating a container inside every #Preview, we can define a reusable preview container for the entire project.
Create a Preview Container
Suppose we have a simple SwiftData model:
import SwiftData
@Model
final class Item {
var title: String
var createdAt: Date
init(title: String, createdAt: Date = .now) {
self.title = title
self.createdAt = createdAt
}
}
We can add a preview container as an extension of ModelContainer:
extension ModelContainer {
@MainActor
static var preview: ModelContainer {
let schema = Schema([
Item.self
])
let configuration = ModelConfiguration(
schema: schema,
isStoredInMemoryOnly: true
)
do {
let container = try ModelContainer(
for: schema,
configurations: [configuration]
)
let context = container.mainContext
context.insert(
Item(
title: "Read Swift book"
)
)
context.insert(
Item(
title: "Build iOS app"
)
)
context.insert(
Item(
title: "Learn SwiftData"
)
)
return container
} catch {
fatalError(
"Failed to create preview container: \(error)"
)
}
}
}
The important part is:
isStoredInMemoryOnly: true
This keeps the preview database entirely in memory. Preview data does not affect the app’s real persistent store, and every new container starts with a clean database.
Use It in #Preview
Now a SwiftUI preview only needs:
#Preview {
ContentView()
.modelContainer(.preview)
}
This keeps previews small and moves all sample data into one place.
For larger projects, I usually put this code in a dedicated file:
Preview/
└── PreviewContainer.swift
As more SwiftData models are added, they can be included in the same schema and populated with representative sample data.
It is a small abstraction, but it makes SwiftUI previews much easier to maintain.