PrismContainer
Factory for creating ModelContainer instances with sensible defaults.
// In-memory (testing)
let container = try PrismContainer.inMemory(for: [User.self, Post.self])
// Persistent
let container = try PrismContainer.create(
for: [User.self, Post.self],
inMemory: false,
cloudKitContainerID: "iCloud.com.myapp" // optional
)
PrismModelStore
@ModelActor providing generic CRUD for any PersistentModel. Runs on its own ModelContext — safe for background work.
let store = PrismModelStore<User>(modelContainer: container)
// Insert
await store.insert(User(name: "Alice", age: 30))
// Batch insert
let users = names.map { User(name: $0, age: 25) }
await store.insertBatch(users)
// Fetch
let all = try await store.fetch()
let adults = try await store.fetch(
predicate: #Predicate { $0.age >= 18 },
sortBy: [SortDescriptor(\.name)],
limit: 50
)
// Count & exists
let count = try await store.count()
let hasUsers = try await store.exists()
// Delete
await store.delete(user)
try await store.deleteAll()
// Transaction
try await store.transaction { context in
context.insert(User(name: "Bob", age: 28))
context.insert(Post(title: "Hello", authorName: "Bob"))
}
PrismQuery
Fluent query builder that produces a FetchDescriptor.
let query = PrismQuery<User>()
.where(#Predicate { $0.age >= 18 })
.sort(SortDescriptor(\.name))
.limit(20)
.offset(40)
let descriptor = query.build()
let results = try await store.fetch(descriptor)
PrismLiveQuery
Polling-based change detection. Emits count updates via AsyncStream — use to trigger UI re-fetches.
let live = PrismLiveQuery<User>(
container: container,
descriptor: FetchDescriptor<User>(),
interval: 2.0 // poll every 2s
)
for await count in live.countStream() {
print("Users changed: \(count) total")
// Re-fetch on main context
}
countStream() yields Int (not [T]) to avoid Sendable violations with PersistentModel.