Reputation: 527
I'm trying to do what should be a very simple lightweight migration involving the addition of an Entity attribute.
In my AppDelegate I have:
lazy var persistentContainer: NSPersistentContainer = {
let container = NSPersistentContainer(name: "app")
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
return container
}()
I have tried creating a new .xcdatamodel and adding the Entity attribute there, then changing the Model Version
current to this new data model. I have also tried simply adding the Entity attribute to my existing data model.
In both cases when I hit run, Xcode crashes without giving me the ability to read any of the console output, so I am at a loss on how to move forward. (I have done this dozens of times.)
Everything I've read seems to indicate that because adding an Entity attribute is a minor change, a lightweight migration should work, and that both shouldInferMappingAutomatically
and shouldMigrateStoreAutomatically
should default to true
.
There are numerous explanations of how to perform a lightweight migration if using addPersistentStore
but I'm not using that; I'm using loadPersistentStores
and it seems like I'd have to refactor my entire app to change this (and, anyway, everything seems to indicate that loadPersistentStores
is the new / approved way to handle Core Data).
Based on some other SO posts, I've updated my lazy initialization to the following:
lazy var persistentContainer: NSPersistentContainer = {
let container = NSPersistentContainer(name: "app")
let url = NSPersistentContainer.defaultDirectoryURL()
let description = NSPersistentStoreDescription(url: url)
description.shouldAddStoreAsynchronously = true
description.shouldInferMappingModelAutomatically = true
description.shouldMigrateStoreAutomatically = true
description.isReadOnly = false
container.persistentStoreDescriptions = [description]
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
return container
}()
I put a breakpoint right at the if let error = error
and was able to capture the console before Xcode crashes. Here is the result:
CoreData: warning: View context accessed for persistent container app with no stores loaded
CoreData: warning: View context accessed for persistent container app with no stores loaded
CoreData: error: -addPersistentStoreWithType:SQLite configuration:(null) URL:file:///var/mobile/Containers/Data/Application/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/Library/Application%20Support/ options:{
NSAddStoreAsynchronouslyOption = 1;
NSInferMappingModelAutomaticallyOption = 1;
NSMigratePersistentStoresAutomaticallyOption = 1;
NSReadOnlyPersistentStoreOption = 0;
}
... returned error Error Domain=NSCocoaErrorDomain Code=256 "The file couldn’t be opened." UserInfo={NSSQLiteErrorDomain=14, NSUnderlyingException=unable to open database file} with userInfo dictionary {
NSSQLiteErrorDomain = 14;
NSUnderlyingException = "unable to open database file";
}
(lldb)
But now I am (again) stuck. I cannot imagine why the app would be unable to open the database file and have no idea how to determine what's preventing it.
Upvotes: 1
Views: 1372
Reputation: 527
I removed the new code from my lazy initialization and returned it to simply:
lazy var persistentContainer: NSPersistentContainer = {
let container = NSPersistentContainer(name: "bartender")
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
return container
}()
I put the breakpoint at the same place and this time found this message in the console: Cannot migrate store in-place: Validation error missing attribute values on mandatory destination attribute
That led me to the idea of setting a Default Value
in the new attribute of the Entity I'd updated, and now Xcode is no longer crashing, so it seems the problem is fixed!
Upvotes: 2