iOS Development, iOS Interview Study Notes, Swift

iOS Persistence and Core Data part2

Apple Definition: “Core Data is a framework for managing and persisting an object graph”

What is Core Data?

In the most basic sense it helps us as developers save our data to disk and retrieve it later.
It gets more complicated than that. Let’s get a clear picture of what an object graph is. Most of us are familiar with a mathematical graph but it’s not that kind of graph. The best way to know what a graph is, is to look at a picture of one.

Image result for object graph

What we have here are rectangles and lines. The rectangles are objects and the lines are the relationships they have with each other. This complicated layout can be handled with Core Data. Core Data is also great when working with massive data sets because it helps us sort and filter the data as well as perform undo and redo operation.

Core Data Structure

When I first started learning about Core Data I was very confused about what is referred to as the Core Data Stack Let me try and break it down for you. There are four components of Core Data

  • Persistent Store
  • Managed Object Model
  • Managed Object Context
  • Persistent Store Coordinator

Persistent Store

This is the actual file containing the saved data.
An instance of NSPersistent Store
Be in be one of several formats

Let’s think of the Persistent Store as our Department Store. This is the building that has everything inside.

Managed Object Model

Includes the data scheme
This is where we tell Core Data the type of data that we have
Core Data has entities (class or struct), attributes (properties), and relationships
This can be created as a file in Xcode, but can also be created programmatically

Everything that is inside of store split up. We have store departments, staff, merchandise, etc. These would be the entities. Staff includes managers, cashiers, stockroom attendees, janitors, etc. These would be the attributes. However these attributes can also be Entities because then a manager has a name, salary, schedule, departments that they oversee. And now you start to see what it means by relationships. Some items connect to others. The Staff entity will be connected to the store department entity that will have a relationship to the merchandise entity. And now it’s a jumbled up mess like our picture above.

Managed Object Context

This is how we interact with the Core Data data
Does the creation, deletion, changes, saving to the Core Data objects/data
Contains Managed Objects
Cannot have Core Data object/managed object outside of a managed object context
It is our primary interface to the stack

In our store analogy the Managed Object Context is how the customer interacts with the store. They don’t know all that is involved in the background they want to go in buy some items, maybe talk to an employee or two and walk out.

Persistent Store Coordinator

Ties everything together
Manages persistent stores
Goes in between the Managed Object Context which is how we interact with the data and the Persistent Store which is the actual data itself

This is our store manager. Who has access to all the information about the store and is informed of everything that is going on. When an item gets purchased the store manager knows about it and can see the change in inventory happening. He can then go and order more when necessary.

How does the Data get loaded?

Our app launches and we need to load the data onto our application so we can display it and interact with it. How do we get it?

The data is living inside our Persistent Store. We have a Managed Object Model that has all the information on the layout of the data.

1. We create an instance of the Persistent Store Coordinator and we give it a Managed Object Model. We tell it this is the data we have and how it’s all laid out.
2. The Persistent Store Coordinator will then create a connection to the Persistent Store which is just a file (url) with our data.
3. The last step is for us to create the Managed Object Context and we tell it about the Persistent Store Coordinator and they will then be connected.

Now when we make changes to the data on the Managed Object Context it will not be saved until we call save() which will bundle it up and send it to the Persistent Store Coordinator and he will then send it to the Persistent Store where all the changes will be applied.

How to Use the Core Data Stack

I am not going to go over how to build a whole app with Core Data there are plenty of tutorials and books that will show you how to do this. Instead I am going to go over the class that should be built so that you can access the Managed Object Context that will manipulate the data. Apple has made it very easy to do this now as they have built NSPersistentContainer and all we need to do is create an instance of it and use it.

import Foundation
import CoreData

class CoreDataStack {
   // This will allow us to have a shared instance of the stack throughout the app
   static let shared = Stack()

   // A lazy var that will be created when it is first accessed
   lazy var container: NSPersistentContainer = {

      // Creates the Persistent Container which is basically an encapsulated version of our Data Stack it contains the 4 pieces and only allows the Object Context to be accessed by the rest of the app as that is how we will interact with our data.
// The name should match the name of your model file because the persistent container will look for a model file with that same name
      let container = NSPersistentContainer(name: "ModelName")
      
      // After it's created all we have to do is call loadPersistentStores as this will do everything else for us. It loads the store(s), the managed object model, the persistent store coordinator and connects it all for us. This takes a closure that returns optional data and an optional error that we can check to see if everything was loaded successfully. 
      container.loadPersistentStores { (_, error) in 
         if let error = error {
            fatalError("Error loading Core Data stores: \(error)")
         }
      }
      return container
   }()

   // This allows us to access the Managed Object Context without having to access the container each time. This is just for convenience. We can do CoreDataStack.shared.mainContext for easy access to it. 
   var mainContext: NSManagedObjectContext {
      return container.viewContext
   }
}

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s