Core Data : Custom NSManagedObject and CRUD Service Demo

Abhishek Thapliyal
Aug 9, 2017 · 5 min read

This story is basically get to know how we can do basic CRUD operations in core data i.e.

  1. C : Create an entity
  2. R : Retrive an entity
  3. U: Update an entity
  4. D: Delete entity

Lets do all step by step

Create a new Xcode project and select “Use Core Data” as shown below

After that you will see “CoreDataDemo.xcdatamodelId” i.e. “ProjectName.xcdatamodelId”. Tap on it and select add new entity button below

You will get a blank entity, Double click on it to rename it as “Employee”.
Now add attributes/Table fields
1. name String
2. empId String
3. contact Integer 64
4. address String
5. emailId String

The Employee table looks like

Now in the attribute inspector you will see class option with drop down menu, select Manual/None.
We need subclass of NSMangedObject Class to map values from class object to database entity.
Go to editor and select Create NSMangedObject subclass.

Followed by this you will get Model option to choose, select CoreDataDemo and then select table of which you need subclass, select Employee table.

You will see 2 new files named
1. Employee+CoreDataClass.swift
2. Employee+CoreDataProperties.swift

Congratts!!! you have successfully created subclass of your table.

Create a model class named EmployeClass which is used to show employee data in view controller. Add variable like this

class EmployeeClass: NSObject {

public var empId: String?
public var name: String?
public var contact: Int64?
public var emailId: String?
public var address: String?

override init() {}
}

NOTE : Two classes are used so that business logic and database logic should be independent

Now create a new File, subclass of NSObject and name it CoreDataService.
Go to AppDelegate class and move all core data code to CoreDataService class.
Create static intializer to make this class singleton

static let shared = CoreDataService()

Now add a new file Name DBManager and add static intializer.

static let shared = DBManager()

In this class will do all operations related to database. Let’s start

Create a new Entity

public func addEmployee(employee: EmployeeClass) {

let dbManager = CoreDataService.shared
let context = dbManager.dbContext
let entityDesc = NSEntityDescription.entity(forEntityName: “Employee”, in: context)
guard let entity = entityDesc else { return }
let employeeObj = Employee(entity: entity, insertInto: context)

employeeObj.empId = employee.empId
employeeObj.name = employee.name
employeeObj.address = employee.address
employeeObj.contact = employee.contact!
employeeObj.emailId = employee.emailId

do {
try context.save()
} catch let error as NSError {
print(“Unable not save Employee \(error), \(error.userInfo)”)
}
}

In this function you will see the parameter is object of type class EmployeeClass i.e. you will wrap the values from your view controller’s fields and pass this function as shown

let emp = EmployeeClass()
emp.empId = “101”
emp.name = name.text
emp.emailId = email.text
emp.contact = Int64(contact.text)
emp.address = address.text

DBManager.shared.addEmployee(employee: emp)

Retrieve an entity

public func getEmployeeFromDB(empId: String) -> Employee? {

let dbManager = CoreDataService.shared
let context = dbManager.dbContext
let entity = NSEntityDescription.entity(forEntityName: “Employee”, in: context)

let fetchRequest = NSFetchRequest<NSFetchRequestResult>()
fetchRequest.entity = entity
let predicate = NSPredicate(format:”empId == %@”, empId)
fetchRequest.predicate = predicate

do {
let results = try context.fetch(fetchRequest)
guard let employee = (results as? [Employee])?.first else { return nil }
return employee
} catch let error as NSError {
print(“Unable to Fetch Employee \(error), \(error.userInfo)”)
}

return nil
}

public func getEmployee(empId: String) -> EmployeeClass? {

guard let employeeObj = self.getEmployeeFromDB(empId: empId) else { return nil }

let employee = EmployeeClass()

employee.empId = employeeObj.empId
employee.name = employeeObj.name
employee.address = employeeObj.address
employee.contact = employeeObj.contact
employee.emailId = employeeObj.emailId

return employee
}

Here you will pass employee Id to get all details of employee wrapped in object of EmployeeClass . You will observe that here there are 2 methods

1. getEmployeeFromDB : Will give data in the form of custom NSMangedObject object.

2. getEmployee : Will map values from (NSMangedObject) database object to model class EmployeeClass.

Update an entity

public func updateEmployee(employee: EmployeeClass) -> Bool {

guard let empId = employee.empId, let employeeObj = self.getEmployeeFromDB(empId: empId) else { return false }
employeeObj.name = employee.name
employeeObj.address = employee.address
employeeObj.contact = employee.contact!
employeeObj.emailId = employee.emailId

let dbManager = CoreDataService.shared
let context = dbManager.dbContext

do {
try context.save()
return true
} catch let error as NSError {
print(“Unable not Update Employee \(error), \(error.userInfo)”)
}

return false
}

Which ever employee’s data you want to update wrap those values in EmployeeClass object. Make sure the empId should not be updated i.e. you need to use same empId for which employee details needed to update.

let emp = EmployeeClass()
emp.empId = “101”
emp.name = name.text
emp.emailId = email.text
emp.contact = Int64(contact.text)
emp.address = address.text

DBManager.shared.updateEmployee(employee: emp)

It will return Bool to ensure that values are updated or not

Delete an Entity

public func deleteEmployee(empId: String) {

let dbManager = CoreDataService.shared
let context = dbManager.dbContext
let entity = NSEntityDescription.entity(forEntityName: “Employee”, in: context)

let fetchRequest = NSFetchRequest<NSFetchRequestResult>()
fetchRequest.entity = entity
let predicate = NSPredicate(format:”empId == %@”, empId)
fetchRequest.predicate = predicate

do {
let results = try context.fetch(fetchRequest)
guard let obj = (results as? [Employee])?.first else { return }
context.delete(obj)
try context.save()
} catch let error as NSError {
print(“Unable to Delete Employee \(error), \(error.userInfo)”)
}

Pass the empId whichever you need to delete from local data.

DBManager.shared.deleteEmployee(empId: “101”)

So these are basic operations in core data. This blog will give you an basic idea about work flow in core data.

You can download project from here
For basic & more information go to Apple Link

Abhishek Thapliyal

Written by

Mobile Application Developer | iOS + Swift | React-Native @NickelfoxStudio

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade