CoreData result class has 'Sendable' warnings

In an iOS viewController, I use the NSDiffableDataSource to populate a tableView from the results of a CoreData fetchController. The result class is defined by CoreData - in this case a class named CDFilterStack.

In xCode 16.0 Beta with strict concurrency checking = 'Complete' the CDFilterStack class has this warning everywhere it is referenced.

"Type 'CDFilterStack' does not conform to the 'Sendable' protocol; this is an error in the Swift 6 language mode."

The class definition of CDFilterStack is not editable because it is generated by CoreData.

I think I need to mark this class (and other similar classes) as @preconcurrency... but how & where?

Here's one method sample that generates three of these warnings

func initialSnapShot() -> NSDiffableDataSourceSnapshot<Int, CDFilterStack> {

        var snapshot = NSDiffableDataSourceSnapshot<Int, CDFilterStack>()

        if let sections = dataProvider.fetchedResultsController.sections {
            for index in  0..<sections.count
              {
                let thisSection = sections[index]

                guard let sectionStacks = thisSection.objects as? [CDFilterStack]
                else { continue}
                snapshot.appendSections([index])
                snapshot.appendItems(sectionStacks)
            }  // for loop that will continue on error in objects

        }
        return snapshot
    }

Careful reading of the various migration guides hasn't produced an example of how to handle this.. (btw the migration guides are nicely done:)

Answered by Will Loew-Blosser in 792555022

My solution:

Add a struct with the same var names as the CoreData Entity class.

Add one more var to hold the NSManagedObjectID.

Add a method (#asStruct) to copy all of the values in the Entity class to the struct.

Everywhere the Entity class was used, change the reference to the new struct.

Finally on the save operation use the NSManagedObjectID to get the managed object back from the data context and update the managed object values as needed from the struct.

Only one of the 18 CoreData entity classes needed this fix. The other 17 lower level entities apparently did not cross the NSDiffableDataSourceSnapshot/Entity class isolation boundary and thus do not cause the 'Sendable' warning.

It would be nice if the CoreData data model supported an option to create either a struct or an Entity class. This would (I guess) save a lot of code changes where two frameworks have interfaces.

Accepted Answer

My solution:

Add a struct with the same var names as the CoreData Entity class.

Add one more var to hold the NSManagedObjectID.

Add a method (#asStruct) to copy all of the values in the Entity class to the struct.

Everywhere the Entity class was used, change the reference to the new struct.

Finally on the save operation use the NSManagedObjectID to get the managed object back from the data context and update the managed object values as needed from the struct.

Only one of the 18 CoreData entity classes needed this fix. The other 17 lower level entities apparently did not cross the NSDiffableDataSourceSnapshot/Entity class isolation boundary and thus do not cause the 'Sendable' warning.

It would be nice if the CoreData data model supported an option to create either a struct or an Entity class. This would (I guess) save a lot of code changes where two frameworks have interfaces.

CoreData result class has 'Sendable' warnings
 
 
Q