My AppDelegate came with the following all familiar Core Data template:
lazy var persistentContainer: NSPersistentContainer = {
let container = NSPersistentContainer(name: "newsapp")
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
return container
}()
It also had the following comment:
The persistent container for the application. This implementation creates and returns a container, having loaded the store for the application to it. This property is optional since there are legitimate error conditions that could cause the creation of the store to fail.
Replace this implementation with code to handle the error appropriately.
fatalError()
causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.Typical reasons for an error here include:
- The parent directory does not exist, cannot be created, or disallows writing.
- The persistent store is not accessible, due to permissions or data protection when the device is locked.
- The device is out of space.
- The store could not be migrated to the current model version.
Check the error message to determine what the actual problem was.
True, calling it quits in this place is a bad idea not only it is not allowed in production apps, but because, as I read elsewhere, if a data store gets corrupted for any reason, a user would have to reinstall the app not knowing about that. A user can delete and forget my app just as well in this case.
Now, how one is supposed to handle such and other errors here? Even if I write the error handling code, how do I test that is works correctly if these errors almost never happen?
I looked all over, but couldn't find any example.
NSPersistentContainer simplifies the creation and management of the Core Data stack by handling the creation of the managed object model ( NSManagedObjectModel ), persistent store coordinator ( NSPersistentStoreCoordinator ), and the managed object context ( NSManagedObjectContext ).
Notice that there is no explicit instantiation of NSManagedObjectModel, NSPersistentStoreCoordinator, or NSManagedObjectContext. This is abstracted away by the NSPersistentContainer class. A Core Data stack without a persistent store isn't terribly useful.
Fortunately, the NSPersistentContainer class provides access to the managed object model, the managed object context, and the persistent store coordinator. In Mastering Core Data With Swift 3, we take a different approach by building a Core Data stack from scratch.
The NSPersistentStoreDescription class is another new addition to the Core Data framework. It encapsulates the information and configuration to add a persistent store to the persistent store coordinator. As the name of the class implies, it describes a persistent store.
In most cases fatalError
is the only "handling" that makes sense for this error, though you might want to display an alert telling the user what's happening first. If you need your persistent store but you can't load it, you're kind of screwed.
Some of those errors are things that should come up during development. Like store migration or data protection problems-- you need to be testing that, and if necessary fixing the app before release. For cases like that, fatalError
actually makes sense because only you will ever experience it.
Of those listed examples, the only one that might come up unexpectedly that can be awkward to test is the device being out of space. You could check available space and alert the user. But you still don't have any way to recover from the error unless your app is using a lot of space that you can clear out. If this happens, iOS will already be warning them that they're running out of space, so doing it yourself isn't necessary.
If you don't have a lot of data you can clear out, fatalError
still makes sense here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With