I have a Core Data data model with several model versions (kept to allow migrations). My entities have the codegen
setting set to Manual / none
, and I have corresponding classes in my codebase where I hook into certain methods like validateForUpdate
, awakeFromInsert
, etc:
@objc(Book)
class Book: NSManagedObject {
@NSManaged var title: String
override func validateForUpdate() throws {
try super.validateForUpdate()
try customValidation()
}
}
During migration of an old store, it is necessary for me to load the old store using the old model version and perform some updates to managed objects. However, the validation from the NSManagedObject
class still runs, even though this was only designed to run against the latest version. It may refer to attributes that don't exist in the old version, giving me unrecognized selector
errors.
An example of the code I'm using to load a store with the old model is:
// book_5 is the name of the older model version
let model = NSManagedObjectModel(contentsOf: Bundle.main.url(forResource: "books_5", withExtension: "momd")!)!
let container = NSPersistentContainer(name: "TestModel", managedObjectModel: model)
let description = NSPersistentStoreDescription(url: storeLocation)
container.persistentStoreDescriptions = [description]
container.loadPersistentStores { _, _ in
let entity = model.entitiesByName["Book"]!
let newBook = NSManagedObject(entity: entity, insertInto: container.viewContext)
newBook.setValue("Test Book", forKey: "title")
try! container.viewContext.save()
}
When inserting the object into the context, the awakeFromInsert
method is fired, triggering an error because it refers to attributes that only exist in the newest model version.
Is there a way to workaround this? I feel like this should be possible because manipulating source entity objects in a custom entity mapping during a heavyweight migration does not hit the same issue.