If you’re targeting iOS 10 and above, you’ve got the opportunity to pick your poison when it comes to creating the Core Data stack.
You could opt for the process I described in Creating the Core Data Stack with Backwards Compatibility in Swift — that process still works perfectly fine in iOS 10+.
Alternatively, you could use the new
NSPersistentContainer class if you want to write a few less lines of code and keep up-to-date with the latest framework enhancements!
What’s the point of the “Core Data stack”?
It’s important to keep in mind the fundamental goal with creating the “Core Data stack”. At the end of the day, we’re all just trying to get our hands on an instance of
Nearly every Core Data framework Type that we interact with requires an instance of
NSManagedObjectContext to do its work. Whether it’s
NSEntityDescription to initialize new
NSManagedObject instances, an
NSFetchRequest to retrieve data, or an
NSFetchedResultsController to keep our UIs in sync, we’re always depending on
So the bottom-line goal of setting up the “stack” is to configure all the plumbing necessary for our apps to work with the “under the hood” stuff of Core Data. The thing we interact with constantly is that all-valuable
Creating the stack with NSPersistentContainer
NSPersistentContainer saves a few keystrokes and abstracts away a few of the moving parts when it comes to setting up the Core Data stack. Compare my Backwards Compatibility post if you’re curious about what’s being simplified.
So… how’s it done?
First: Make sure you’re targeting iOS 10+, macOS Sierra (10.12)+, watchOS 3+, or tvOS 10+
NSPersistentContainer is only available in Apple’s latest platform versions (latest as of May, 2017).
Once you’ve ticked the build target prerequisite above, check out this code example:
Step-by-step through the code
NSPersistentContainer can be seen as a 3 step process.
1 – Initialize an
NSPersistentContainer instance. Its only parameter is the
name of the model (look at your .xcdatamodeld file for this)
2 – Call
loadPersistentStores on the container instance. This function executes asynchronously, so to hook back in and continue doing things when the function is finished with its work, you supply a completionHandler.
3 – Guard against errors and use the container’s
viewContext property, which is the
NSManagedObjectContext instance you need. I haven’t written in detail about this (yet), but in my Pluralsight course on Core Data in Swift, I go over how to take the managed object context and follow a dependency injection pattern so that you isolate where it’s created, and use the single instance throughout your app in a way that’s testable.
One consideration that I would encourage you to think about is the
guard statement. Ask: “Is
fatalError really the best thing for me to do?”
A lot of apps that use Core Data really can’t continue past this point if the persistent store can’t be loaded. In that case, the
guard may not be so bad. If you can fall back to an alternate screen that doesn’t rely on Core Data though, that might be a more pleasant experience for your users than simply crashing with a fatal error.
This is the simplest way to use
NSPersistentContainer to create your Core Data stack, and that’s where I want to leave it for today!
Thank you, as always, for your interest in the content I’m creating!
And yes, if you’re learning Core Data, I would love to contribute to your understanding of the framework. That’s why I built Core Data Fundamentals with Swift for Pluralsight! If you’re a subscriber, I’d be thrilled to engage with you on the course!