How do I safely access Core data NSManagedObject attributes from SwiftUI view using the swift concurrency model.
My understanding is we need to enclose any access to NSManageObject attributes in await context.perform {}.
But if I use it anywhere in a view be that in the body(),
or init()
or .task()
modifier I get the following warnings or errors:
for .task{}
modifier or if within any Task {}:
Passing argument of non-sendable type 'NSManagedObjectContext.ScheduledTaskType' outside of main actor-isolated context may introduce data races this happens even if I create a new context solely for this access.
if within body()
or init():
'await' in a function that does not support concurrency
but we cant set body or init() to async
an example of the code is something along the lines of:
var attributeString: String = ""
let context = PersistentStore.shared.persistentContainer.newBackgroundContext()
await context.perform {
let backgroundObject = context.objectWithID(objectID)
attributeString = backgroundObject.attribute!
}
The trick is to get the
nsmanagedObject.objectID
before your perform block, then inside perform you just need to find the object again in the background context using that ID. Now you have an object that is safe to access from the background, e.g.