How to safely access Core data NSManagedObject attributes from a SwiftUI view using swift concurrency model?

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 {
    attributeString = nsmanagedObject.attribute!
}

Passing argument of non-sendable type 'NSManagedObjectContext.ScheduledTaskType' outside of main actor-isolated context may introduce data races

What version of Xcode are you using?

The following code compiles for me:

import Foundation
import CoreData

func test(context: NSManagedObjectContext) {
    Task {
        await context.perform {
            print("Hello Cruel World!")
        }
    }
}

print("just a demo")

This doesn’t use NSManagedObjectContext.ScheduledTaskType, so I’m curious how you managed to get that error.

For context (hey hey!), I’m using Xcode 15.0 and compiling in a macOS command-line tool project.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

You probably want to use performAndWait in body, those closures don't support concurrency so you need to remove that from the scope. perform() and performAndWait were both introduced before Swift Concurrency was a thing. The scheduled task variant is meant to work with SwiftConcurrency.

let context = //new background context
context.performAndWait {
    //do your work
}
How to safely access Core data NSManagedObject attributes from a SwiftUI view using swift concurrency model?
 
 
Q