NSPersistenceContainer returns nil?

Viewed 68

When setting up a CoreData stack, I noticed that NSPersistenceContainer may return "nil" if the name of the model is spelled wrong.

...

let container = NSPersistentContainer(name: name)
                
guard container != nil else { // warning here ... see explanation below

    promise(.failure(.objectModelNotFound))
    return
}

In the code fragment above (which is part of utility function) the compiler complains about the guard statement with a warning: "Comparing non-optional value of type 'NSPersistentContainer' to 'nil' always returns true".

The init for the NSPersistenceContainer is declared as:

convenience init(name: String)

To summarise: If the name of the model is wrong, the code in the guard's else statement is reached, and a message in the console window says: "CoreData: error: Failed to load model named XYZ"

The question then is, is it okay for NSPersistentContainer to do so? Or maybe it was stated incorrectly in the documentation?

And if not, what is the correct way to handle the situation in code without getting a warning?

1 Answers

Just creating an NSPersistenceContainer does not set up the Core Data Stack. You still need to call loadPersistentStores on this container. If you look at the default stack that Xcode can create for you you can see that the default implementation allows you to check that the container is set up correctly:

container.loadPersistentStores(completionHandler: { (storeDescription, error) in
    if let error = error as NSError? {
        // 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.
        */
        fatalError("Unresolved error \(error), \(error.userInfo)")
    }
})

And in this block you can deal with the error.

Passing in an Incorrect name comes under the category of a developer error. You should know the name of your model, that exists in your bundle, and if it doesn't exist then you have a big problem.

Related