Using Core Data with the Swift 6 language mode

I'm starting to work on updating my code for Swift 6. I have a number of pieces of code that look like this:

private func updateModel() async throws {
    try await context.perform { [weak self] in
        // do some work
    }
}

After turning on strict concurrency checking, I get warnings on blocks like that saying "Sending 'self.context' risks causing data races; this is an error in the Swift 6 language mode."

What's the best way for me to update this Core Data code to work with Swift 6?

Answered by DTS Engineer in 790438022

Yeah, the warning is triggered because NSManagedObjectContext is not a Sendable type. Does updateModel need to be isolated to a certain actor? If not, you can consider annotating updateModel with nonisolated, which should calm down the warning.

If updateModel does rely on other isolated and non-sendable variables, check if you can convert them to Sendable types.

Best,
——
Ziqiao Chen
 Worldwide Developer Relations.

Yeah, the warning is triggered because NSManagedObjectContext is not a Sendable type. Does updateModel need to be isolated to a certain actor? If not, you can consider annotating updateModel with nonisolated, which should calm down the warning.

If updateModel does rely on other isolated and non-sendable variables, check if you can convert them to Sendable types.

Best,
——
Ziqiao Chen
 Worldwide Developer Relations.

Thanks! I'm wondering if you have any advice about making an NSManagedObject subclass Sendable? I'm not really sure how I'd go about it.

fwiw, I'm still getting up to speed on Swift concurrency, but I suspect that NSManagedObject is most definitely not sendable.

You can't make NSManagedObject sendable because some member variables in the type are not Sendable. If you do need to pass a managed object across actors, consider the following options:

  1. Pass the objectID (NSManagedObjectID) of the managed object instead, which is Sendable, and can be converted back to a managed object using object(with:).

  2. Pick the information you need from the managed object, package it with a Sendable type, and pass the transformed object across actors.

Best,
——
Ziqiao Chen
 Worldwide Developer Relations.

Using Core Data with the Swift 6 language mode
 
 
Q