Context outside of SwiftUI Views

In a SwiftUI view it is easy to pull mainContext out of the Environment (thanks for that).

I have two questions:

(1) In Nick's code he shows:

let context = self.newSwiftContext(from: Trip.self)

can you say more about this method newSwiftContext(). How should we implement it to fetch a new context from the same container?

(2) In Core Data we usually read from the main context but write to a child of main context off the main thread and then the parent is notified it needs to refresh. How do we do that with SwiftData or is that managed for us?

Thanks,

Daniel

Replies

It seems no method to get the mainContext injected in environment directly, and the context is not sendable, you can not use it on other actor/thread. But you can get the context from your model like model.context.

actor BackgroundActor: ModelActor {
    nonisolated public let executor: any ModelExecutor
    
    init(container: ModelContainer) {
        let context = ModelContext(container)
        executor = DefaultModelExecutor(context: context)
    }
    
    func run(task: (ModelContext) -> Void) {
        task(context)
    }
}

You can use this wrapper like this:

databaseActor.run { context in
    // ....

}
  • container.mainContext can also get the main context

Add a Comment

The documentation for ModelContext says it's Sendable, but when I use the context of the ModelActor above in another actor, I get a warning in Xcode 15 beta 4:

Non-sendable type 'ModelContext' in implicitly asynchronous access to actor-isolated property 'context' cannot cross actor boundary

Calling the run method causes a similar warning. What's happening?

With iOS 17 beta 6, Xcode 15 beta 6, my app crashes with:

dyld[600]: Symbol not found: _$s9SwiftData20DefaultModelExecutorC7contextAcA0D7ContextC_tcfC

No such problem with iOS 17 beta 5.