The bug is in SwiftData’s ModelContext initializer implementation. The initializer checks whether it is running on the main dispatch queue and if so, configures the context as a main context rather than a background context. More details in FB13399899 (Open Radar ID 5518888167014400).
Here is my workaround:
extension ModelContext {
struct UncheckedSendableWrapper: @unchecked Sendable {
let modelContext: ModelContext
}
/// Creates a background context.
///
/// - Remark: This method works around FB13399899, which causes `init(_:)` to sometimes configure the instance
/// as a main context. This method is marked `async` and not `@MainActor`, which guarantees that the method will be
/// called off of the main thread, working around the bug in the initializer implementation.
static func makeBackgroundContext(for container: ModelContainer) async -> UncheckedSendableWrapper {
let modelContext = ModelContext(container)
return UncheckedSendableWrapper(modelContext: modelContext)
}
}
actor MyModelActor: ModelActor {
…
init(container: ModelContainer) async {
let context = (await ModelContext.makeBackgroundContext(for: container)).modelContext
}
…
}