When do we need local device storage in iOS?
- for cache
- when you are not connected to the internet, you still have local data available in your app
Local Data Persistence
- this data will be available whenever you open it
provided by the CoreData framework
SQLite relational database will be used
we won't be writing sql directly
we will be using library
What is relational database?
- Entity Relational Diagram
- relationship
- entities: tables
- attributes: table columns
- core data will take care of database, table...
- all you need to do is to define entity, class and attributes for the entity
- instance of an entity(class): represent a row in the table
- map relationship between core data class and sqlite classes
Steps to use Core Data framework
- define the entities
- specify the attributes
- describe relationships between the entities
- insert data
Core data
- not a database
- act as an interface between SQLite database and your app!
1.managed object context - interact with app
2.persistent container - interact with database tables
How to use SQLite database in xCode?
1.create a project and check "Use Core Data"
2.click on core data file (w10c1_CoreDataApp) and + Add Entity
double-click Entity and rename it to Employee
3.add attributes to the Employee
entity
make sure you check Manual/None
for Codegen (Entity > Inspector > Class > Codegen)
why Manual/None?
- core data will automatically generate a class for you in memory which you will be not seeing physically
- if you want to make sure class exists, do not let core data generate the class for you
- manual/none -> you will have controls over the class
- set to class definition -> core data will also generate the class as well (hard to find bugs since you don't see the class)
4.select Editor > Create NSManagedObject Subclass
, which generates a swift class representing your Entity
result - you should get two new files
5.need a reference to Core Data's managed context variable for CRUD operations
class ViewController: UIViewController {
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
override func viewDidLoad() {
super.viewDidLoad()
}
}
6.CRUD operations
Create
override func viewDidLoad() {
super.viewDidLoad()
addEmployee(name: "John", age: 30, department: "Frontend")
}
func addEmployee(name: String, age: Int, department: String) {
// 1. Create an employee object
let emp = Employee(context: context)
// 2. Set the properties of that object
emp.name = name
emp.age = Int16(age)
emp.department = department
// 3. Use the context variable to save the Employee to the database table
do {
try context.save()
print("Employee saved!")
} catch {
print("Saved failed.")
}
}
How to locate the Core Data SQLite file?
1.Install this software in your Mac: https://sqlitebrowser.org/
2.add path code to AppDelegate.swift > didFinishLaunchingWithOptions
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
let path = FileManager
.default
.urls(for: .applicationSupportDirectory, in: .userDomainMask)
.last?
.absoluteString
.replacingOccurrences(of: "file://", with: "")
.removingPercentEncoding
print("Core Data DB Path :: \(path ?? "Not found")")
return true
}
3.run the app and get the path from the terminal
Core Data DB Path :: /Users/<USER>/Library/Developer/CoreSimulator/Devices/DA892F2C-3C83-4ED4-B5A2-D6D80257BDFC/data/Containers/Data/Application/4DE2AF5B-B77B-412F-B74D-AC3BAA023A8D/Library/Application Support/
4.open Finder > Go > Go to Folder
and copy and paste the path into window
5.open .sqlite
file in DB Browser
Read
override func viewDidLoad() {
super.viewDidLoad()
fetchAllEmployees()
fetchAllEmployees(age: 30)
}
func fetchAllEmployees() {
let fetchRequest: NSFetchRequest<Employee> = Employee.fetchRequest()
do {
let employees = try context.fetch(fetchRequest)
for emp in employees {
print(emp.name ?? "")
print(emp.age)
print(emp.department ?? "")
print("-----------")
}
} catch {
print("Failed to fetch employees")
}
}
func fetchAllEmployees(age: Int) {
let fetchRequest: NSFetchRequest<Employee> = Employee.fetchRequest()
fetchRequest.predicate = NSPredicate(format:"age <= %@", "\(age)")
do {
let employees = try context.fetch(fetchRequest)
for emp in employees {
print(emp.name ?? "")
print(emp.age)
print(emp.department ?? "")
print("-----------")
}
} catch {
print("Failed to fetch employees")
}
}
Update
override func viewDidLoad() {
super.viewDidLoad()
updateEmployee()
}
func updateEmployee() {
let fetchRequest: NSFetchRequest<Employee> = Employee.fetchRequest()
do {
let employees = try context.fetch(fetchRequest)
let firstEmp = employees.first
firstEmp?.age = 30
try context.save()
print("Employee updated")
} catch {
print("Failed to update employee")
}
}
Delete
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
override func viewDidLoad() {
super.viewDidLoad()
deleteEmployee()
}
func deleteEmployee() {
let fetchRequest: NSFetchRequest<Employee> = Employee.fetchRequest()
do {
let employees = try context.fetch(fetchRequest)
if let lastEmp = employees.last {
context.delete(lastEmp)
}
try context.save()
print("Employee deleted")
} catch {
print("Failed to delete employee")
}
}
Top comments (1)
CoreData Studio - This is a good tool to monitor your project and the changes you've made in your app