Type-safe CoreData in Swift

I'm currently migrating a very old CoreData project to SwiftUI but @NSManaged just doesn't work well. To that end I've created a plugin/library GitHub - jjrscott/Mogen: Type-safe CoreData in Swift to replace Xcode's code generation, allowing the correct Swift types and binding to SwiftUI.

@objc(MOAnimal) @objcMembers
public class MOAnimal: NSManagedObject {
    @MGManaged("ebvIndex") var ebvIndex: Int32?
}

struct AnimalView: View {
    @ObservedObject var animal: MOAnimal
    var body: some View {
          TextField("EBV Index", value: $animal.ebvIndex, format: .number)
    }
}

Comments, suggestions welcome.

2 Likes

I don't use CoreData, but in that code, @objc(MOAnimal) seems unnecessary when the type is already MOAnimal. Or is there some sort of underlying Obj-C representation this is fixing?

Without @objc(MOAnimal) the fetch request results on a crash:

error: +[MOAnimal entity] Failed to find a unique match for an NSEntityDescription to a managed object subclass
CoreData: error: +[MOAnimal entity] Failed to find a unique match for an NSEntityDescription to a managed object subclass

I could override MOAnimal.entity to return the correct value but it just wasn't worth the hassle.

It’s because without @objc(MOAnimal), the objc name of the class is ”TheModuleName.MOAnimal". Since Core Data looks up classes by the entity name, it doesn’t find a class named “MOAnimal”, and logs the errors shown above.

1 Like

Quiet, keeping things as close as possible to Apple's code generation seemed the right move.

TBH, given the simplicity of the implementation it would be good to see Apple fold this function into Xcode itself and remove @NSManaged from Swift (possibly along with dynamic). To that end I've created a short pitch here: Move @NSManaged from Swift to CoreData.