If you're reading this, then I assume you are new to Core Data. You may have heard about Core Data and you'd like to find out whether it's a good fit for you or the project you're working on. If this description fits you, then take a seat. This Core Data tutorial teaches you everything you need to know to better understand what Core Data is and isn't.
What Is Core Data
Developers new to the framework very often don't take the time to learn what Core Data is. Not knowing what Core Data is, makes it very hard to understand its ins and outs. I'd like to spend a few minutes exploring the nature of Core Data and, more importantly, clarifying what Core Data is and isn't.
What Are Its Origins
Core Data's a framework developed and maintained by Apple. It's been around for more than a decade and it first made its appearance on macOS with the release of macOS Tiger in 2005. In 2009, the company made the framework available on iOS with the release of iOS 3.
Where Does It Fit In
Core Data is the M in MVC, the model layer of your application. Even though Core Data can persist data to disk, data persistence is actually an optional feature of the framework. Core Data is first and foremost a framework for managing an object graph.
You've probably heard and read about Core Data before taking this course. That means that you may already know that Core Data isn't a database and that it manages your application's object graph. Both statements are true. But what do they really mean?
Managing an Object Graph
Core Data first and foremost manages an object graph. An object graph is nothing more than a collection of objects that are connected with one another. The Core Data framework excels at managing complex object graphs.
It takes care of managing the life cycle of the objects in the object graph and it can optionally persist the object graph to disk. It also offers a powerful interface for searching the object graph it manages.
But Core Data is much more than that. The framework adds a number of other compelling features, such as input validation, data model versioning, and change tracking.
When to Use Core Data
The framework is a perfect fit for a wide range of applications, but not every application should use Core Data. Applications that need a lightweight model layer shouldn't use Core Data. There are many lightweight libraries that provide this type of functionality.
If you're looking for a SQLite wrapper, then Core Data is also not what you need. For a lightweight, performant SQLite wrapper, I highly recommend Gus Mueller's FMDB. This robust, mature library provides an object-oriented interface for interacting with SQLite.
Core Data is an excellent choice if you want a solution that manages the model layer of your application.
How Does It Differ From SQLite
Developers new to Core Data are often confused by the differences between SQLite and Core Data. If you wonder whether you need SQLite or Core Data, then you're asking the wrong question. Remember that Core Data isn't a database.
SQLite
SQLite is a lightweight database that is very performant, and, therefore, a good fit for mobile applications. Even though SQLite is advertised as a relational database, it's important to realize that you, the developer, are in charge of maintaining the relationships between records stored in the database.
Core Data
Core Data goes much further. It provides an abstraction that allows you to interact with the model layer in an object-oriented manner. Every record you interact with is an object. Core Data is responsible for the integrity of the object graph. It ensures the object graph is kept up to date.
Core Data Limitations
Even though Core Data is a fantastic framework, there are several drawbacks. These drawbacks are directly related to the nature of the framework and how it works.
Core Data can only do its magic because it keeps the object graph it manages in memory. This means that it can only operate on records once they're in memory. This is very different from performing a SQL query on a database. If you want to delete thousands of records, Core Data first needs to load each record into memory. It goes without saying that this results in memory and performance issues if done incorrectly.
Another important limitation is the threading model of Core Data. The framework expects to be run on a single thread. Fortunately, Core Data has evolved dramatically over the years and the framework has put various solutions in place to make working with Core Data in a multithreaded environment safer and easier.
For applications that need to manage a complex object graph, Core Data is a great fit. If you only need to store a handful of unrelated objects, then you may be better off with a lightweight solution or the user defaults system.
Exploring the Core Data Stack
Now that you know what Core Data is and what it's not, it's time to zoom in on the building blocks of the framework. It's essential that you understand how the various classes that make the framework tick play together.
The stars of the framework are:
- the managed object model
- the managed object context
- and the persistent store coordinator
This diagram shows how these classes relate to one another. Let's start with the managed object model.
Managed Object Model
The managed object model is an instance of the NSManagedObjectModel
class. While a typical Core Data application has one instance of the NSManagedObjectModel
class, it's possible to have multiple. The managed object model instance represents the data model of the Core Data application.
The above diagram shows that the managed object model is connected to the data model. The data model is represented by a file in the application bundle that contains the data schema of the application. The data schema is nothing more than a collection of entities.
An entity can have attributes and relationships, which make up the data model of the application. Remember for now that the managed object model an instance is of the NSManagedObjectModel
class and that it the data model of the Core Data application represents.
Managed Object Context
A managed object context is represented by an instance of the NSManagedObjectContext
class. A Core Data application has one or more managed object contexts, each managing a collection of model objects, instances of the NSManagedObject
class.
The diagram we explored earlier illustrates that the managed object context receives model objects through a persistent store coordinator. It keeps a reference to the persistent store coordinator of the application.
The managed object context is the object you interact with most. It creates, reads, updates, and deletes model objects. From a developer’s perspective, the NSManagedObjectContext
class is the workhorse of the Core Data framework.
Persistent Store Coordinator
The persistent store coordinator is represented by an instance of the NSPersistentStoreCoordinator
class and it plays a key role in every Core Data application. While it's possible to have multiple persistent store coordinators, most applications have only one. Very, very rarely is there a need to have multiple persistent store coordinators in an application.
The persistent store coordinator keeps a reference to the managed object model and every parent managed object context keeps a reference to the persistent store coordinator. Don't worry about parent and child managed object contexts for now.
The above diagram shows us that a persistent store coordinator is connected to one or more persistent stores. This brings us to the persistent store.
Persistent Store
Remember that Core Data manages an object graph. The framework is only useful if the persistent store coordinator is connected to one or more persistent stores. Out of the box, Core Data supports three persistent store types:
- a SQLite database
- a binary store
- an in-memory store
Each persistent store type has its pros and cons. Most applications use a SQLite database as their persistent store. As I mentioned earlier, SQLite is lightweight and very fast. It is great for mobile and desktop applications.
How Does the Core Data Stack Work
Now that you know what the Core Data stack consists of, it's time to explore how it operates in an application. The heart of a Core Data application is the persistent store coordinator. The persistent store coordinator is instantiated first when the Core Data stack is created.
But to create the persistent store coordinator, we need a managed object model. Why is that? The persistent store coordinator needs to know what the data schema of the application looks like.
After setting up the persistent store coordinator and the managed object model, the workhorse of the Core Data stack is initialized, the managed object context. Remember that a managed object context keeps a reference to the persistent store coordinator.
With the Core Data stack set up, the application is ready to use Core Data to interact with the application’s persistent store. In most cases, your application interacts with the persistent store coordinator through the managed object context.
You will rarely, if ever, directly interact with the persistent store coordinator or the managed object model. As I mentioned earlier, the NSManagedObjectContext
class is the class you interact with most frequently.
The managed object context is used to create, read, update, and delete records. When the changes made in the managed object context are saved, the managed object context pushes them to the persistent store coordinator, which sends the changes to the corresponding persistent store.
If your application has multiple persistent stores, the persistent store coordinator figures out which persistent store needs to store the changes of the managed object context.
In a Nutshell
You now know the fundamentals of the Core Data framework. You're already ahead of the curve because most developers skip this step. The next step you need to take is start using the framework. If you need a hand, I recommend checking out Mastering Core Data With Swift.