SwiftUI Preview with Core Data: invalid NSEntityDescription

311 views Asked by At

I'm trying to have my SwiftUI Previews work with an in memory Core Data Stack (from Xcode Template). As soon as I call Entity.entity(), I get the following error message:

let context = PersistenceController.preview.container.viewContext
let newBoatMO = Entity(entity: Entity.entity(), insertInto: context)

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'An NSManagedObject of class 'Entity' must have a valid NSEntityDescription.'

I checked in that the name in NSPersistentCloudKitContainer(name: is correct, I also checked in my .xcdatamodeld, the Entity name is correct, the module is empty (ie Global Namespace), and I have this @objc(Entity) at the top of my NSManagedObject subclass.

If I use the non-memory Stack, the Preview works. It's as if the Model was not loaded if I use the in-memory Stack.

1

There are 1 answers

2
Arjan On

For me this was fixed by using public convenience init(context moc: NSManagedObjectContext) rather then the designated public init(entity: NSEntityDescription, insertInto context: NSManagedObjectContext?).

So:

Entity(context: context)

instead of

Entity(entity: Entity.entity(), insertInto: context)

Some background:

I had this error when I had 'overridden' the default convenience init(context moc: NSManagedObjectContext). So I solved it by switching (back) to the built-in version.

Before my Location+CoreDataClass looked like this:

@objc(Location)
public class Location: NSManagedObject {
    convenience init(context moc: NSManagedObjectContext) {
        self.init(entity: Location.entity(), insertInto: moc) // <- Error
        timestamp = Date()
    }
}

and afterwards like this:

@objc(Location)
public class Location: NSManagedObject {
    convenience init(into c: NSManagedObjectContext, timestamp: Date = Date()) {
        self.init(context: c) // <- No error
        self.timestamp = timestamp
    }
}

I'm not sure what causes the error, but maybe this helps someone into the right direction. Make sure the self.init(context: c) method you call is this one.