Swift Core Data — The Simple Way

varun singh
9 min readJun 17, 2022

--

Apple’s Core Data is an object graph and persistence framework for Mac OS X and iOS. It debuted with Mac OS X 10.4 Tiger and iPhone SDK 3.0 for iOS. It enables data to be serialised into XML, binary, or SQLite databases using the relational entity–attribute model.

What is persistence framework?

Frameworks that persist (store) data, usually in a database, are referred to as persistence frameworks. Note that, depending on the framework, a persistence framework can persist to anything in reality, even an XML file. It’s a layer that sits between the database and the application’s entities.

Persistence frameworks contain their own set of rules for extracting data, persisting it, dealing with, and managing stale or filthy data in a prescribed manner, loading data and associated data, and so on.

What is Core Data?

Core Data is not a database. Core Data is a framework for managing an object graph. Core Data can use SQLite as its persistent store, but the framework itself is not a database.

The Core Data framework is in charge of handling the objects in the object graph’s life cycle. It can save the object graph to disc if desired, and it has a robust interface for querying the object graph it manages.

if we sum up what is core data, so answer is core data is a framework that lies in M (Model) of MVC Structure which basically manages the object graph (Object graph is a collection of object that are connected to one another), and persists data to disk.

When to use Core Data?

  • If we are in search of light weight model layer then core data shouldn’t be our first choice.
  • if we are looking for light weight SQLite wrapper then also it’s not a good choice.
  • it is an excellent choice if we want to use it to manage the model layer of our application in MVC.

What‘s the difference between Core Data and SQLite?

Core Data is a framework and SQLite can be used as a persistent store, so question itself is wrong to ask. SQLite is a lightweight database with a very good performance making it fit for mobile devices. While Core data goes further and provides Object Orient Abstraction, in which it interacts with model layer in object-oriented way. Core data is responsible for the integrity of object graph i.e it maintains that object graph is kept upto-date.

Drawbacks of Core Data

  • Records needs to be in memory, it means suppose there are 1000 records and we need to delete them then Core Data will firstly load 1000 data in memory and then only will be able to delete it.
  • Designed to run on single thread.

Exploring Core Data Stack

Three major things in the stack are

  • Managed Object Model — it’s an instance of NSManagedObjectModel and NSManagedObjectModel instance represents the data model of core data application
  • Managed Object Context — it’s an instance of NSManagedContextModel. Core Data class can have one or more instances. Each NSManagedContextModel manages collection of managed objects (NSManagedObject). It receives the model object through a persistence store coordinator. It’s the object with which we interacts the most as it Creates, Reads, Updates & Deletes (CRUD) model objects.
  • Persistent Store Coordinator: It is represented by instance NSPersistentStoreCoordinator class it plays key role in core data application, usually there is only one instance of this class. It keeps the reference to managed object model and every parent managed object context keeps the reference of persistence store coordinator.

What is a persistence store?

As core data manages object graph, and it will be function only when persistentStoreCoordinator is connected to two or more persistent store. So core supports three type of persistent stores.

  • SQLite
  • Binary
  • In-Memory

How Core Data works?

Persistent Store Coordinator is heart of Core Data, it is instantiated first when core data stack is created, and to create Persistent Store Coordinator we need Managed Object Model because store coordinator needs to know what the data schema of application looks like. And after creating Persistent Store Coordinator and Managed Object Model, Managed Object Context is initialised. Now when core data stack is setup then it’s ready to communicate with persistent store.

So CURD happens in ManagedObjectContext which pushes them to persistent store coordinator which sends the changes to corresponding persistent store.

Let’s write some code to create core data !

Now let’s understand the core data by implementing a simple project in which we will create a model for chocolate store having various chocolate from various chocolate factories. So we will be storing chocolate details in separate entity and company info in separate entity. Let’s begin by creating our two entities.

Fig.1 Creating New Project, make sure to click on the checkbox Use Core Data.

Create your project and click on use core data to create the Data Model.

Fig.2 Now go to CoreDataModel

Now click on the Add Entity button at bottom left corner which creates the Entity which will be visible in entities section in the left panel.

Fig.3 coreDataModel Screen

Now inside the entity we can create our attributes and relationships, specifying the type of attributes. While creating relationship we need to write the name of our relationship, destination(i.e with which entity we want to relate it, and reverse which signifies whether we want to reversely relate that entity to any other relationship. Now in right section we can see class section from which we have three different options to select under codegen.

Choose Class Definition when you don’t need to edit the properties or functionality of the managed object subclass and properties files that Core Data generates for you. The generated source code doesn’t appear in your project’s source list. Xcode produces the class and properties files as part of the build process and places them in your project’s build directory.

Choose Category/Extension to add additional convenience methods or business logic inside your managed object subclass. This option allows you take full control of the class file, while continuing to automatically generate the properties file to keep it up-to-date with the model editor. It’s up to you to create and maintain your class manually.

Choose Manual/None to edit the properties in your managed object subclass, for example, to alter access modifiers, and to add additional convenience methods or business logic. Using this option, Core Data doesn’t generate any files to support your managed object. You create and maintain your class, including its properties, manually. Core Data then locates these files using the values you supply in the class name and module fields.

Fig.4 so we will select Manual/None and will create class by ourselves by clicking on Editor and Create NSManagedObject.

Now we will create the core data class and core data property class by using the Xcode interface which automatically generates the code for same.

Fig.5 Data model selection screen

Now we will select for which of the following persistent store we would like to create NSManaged object class, as shown in Fig.5

Fig.6 Entity selection screen

As shown in Fig.6, now we will select the entities for which we need to create NSManagedObject Class and click next.

Now our model is created and we can see our coreData Files created with name YOUR_ENTITY_NAME + CoreDataClass and YOUR_ENTITY_NAME + CoreDataProperties, as shown in Fig.7.

Fig.7 Showing CoreDataClass and CoreDataProperties

How to use CoreData in our Project?

We create our viewModel after creating the dataModel.

import Foundationstruct ChocolateModel {
var flavour: String?
var id: String?
var name: String?
}

Let’s look at how our coreDataManager.swift looks like

import Foundation
import CoreData
import UIKit
class ChocolateCoreDataManager {

// Here we created the managed object context
var context: NSManagedObjectContext?

// Now we will create an instance for our Chocolate entity
private var models = [ChocolateEntity]()
init() { // Now we will create an instance of appDelegate.
// Crucial role of the UIApplicationDelegate singleton is to store your app’s central data objects or any content that does not have an owning view controller.
guard let appDelegate = UIApplication.shared.delegate as AppDelegate else { return } // The persistent container gives us a property called viewContext , which is a managed object context: an environment where we can manipulate Core Data objects entirely in RAM. context = appDelegate.persistentContainer.viewContext
}
func save() {
// Now we will handle the optional value of context by checking whether it is nil using guard let
guard let context = context else { return }
do {
// context.save() saves the data to database and return true if save succeeds else false
try context.save()
} catch {
let nsError = error as NSError
fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
}
}
// Now we create a function to add New Chocolates to the DB. we will create an instance of ChocolateEntity and will use the same to assign data to new chocolate.func addChocolate(name: String, id: String, flavour: String) {
guard let context = context else { return }
let newItem = ChocolateEntity(context: context)
newItem.name = name
newItem.id = id
newItem.flavour = flavour
save()
}
// Now we will create a function to fetch all the chocolates from the core data for that we will create an instance of NSFetchRequest with the name of entity i.e "ChocolateEntity here".func fetchChocolate() -> [ChocolateEntity] {
guard let context = context else { return []}
let request = NSFetchRequest<ChocolateEntity>(entityName: "ChocolateEntity")
do {
try models = context.fetch(request)
} catch let error {
print("Error loading data \(error)")
}
return models
}
// What if we want on particular format of data to be fetched from database, for that we use NSPredicate, in which we can format the the of data we want for eg: we used "name CONTAINS[c] 'Cadbury'" i.e: we filtered all the data having name containing Cadburyfunc fetchCadburyChocolate() -> [ChocolateEntity] {
guard let context = context else { return [] }
let request: NSPredicate<ChocolateEntity> = ChocolateEntity.fetchRequest()
request.predicate = NSPredicate(format: "name CONTAINS[c] 'Cadbury'")
do {
models = try context.fetch(request)
`} catch let error as NSError {
print("Could not fetch. \(error)")
}
return models
}
}

Now we will look at implementation that how do we call the coreDataManager functions in our view named HomeViewController.swift.

let chocolateCoreDataManager = ChocolateCoreDataManager()
let companyCoreDataManager = CompanyCoreDataManager()
var chocolateEntity = [ChocolateEntity]()
var companyEntity = [CompanyEntity]()
// Function for create action when done button clicked, i.e which create the data to database@objc func doneButtonClicked() {
chocolateCoreDataManager.addChocolate(name: (choclateTextField.text?.count ?? 0)>0 ? choclateTextField.text! : "N/A", id: "12233", flavour: "Chcoclate")
companyCoreDataManager.addCompany(name: (companyTextField.text?.count ?? 0)>0 ? companyTextField.text! : "N/A", id: "98234")
companyEntity = companyCoreDataManager.fetchCompany()
chocolateEntity = chocolateCoreDataManager.fetchChocolate()
tableView.reloadData()
}
// Function for fetchAll data action when fetch button clicked@objc func fetchButtonClicked() {
companyEntity = companyCoreDataManager.fetchCompany()
chocolateEntity = chocolateCoreDataManager.fetchChocolate()
tableView.reloadData()
}
// Function for fetchAll "Cadbury" data action when fetch Cadbury chocolates button clicked@objc func fetchCabury() {
companyEntity = companyCoreDataManager.fetchCompany()
chocolateEntity = chocolateCoreDataManager.fetchCadburyChocolate()
tableView.reloadData()
}

Here is the simulator demo of our project how functionalities will work in an actual device.

I hope you all have a clear idea of how actually coreData works, do give it a clap if you liked the post and share it. Thank you.

--

--

varun singh
0 Followers

iOS Developer | Tech Enthusiast | Self- learner | Fullstack MERN Developer