So, what did we learn in lesson 3 of module 5 of the CWC+ iOS Dabatases course?
Well, firstly, that Xcode creates a lot of dummy code for demonstration purposes that we don’t need to use.
More usefully, our main top-level Swift file contains these essential pieces of code:
import SwiftUI
@main
struct DemoApp: App {
let persistenceController = PersistenceController.shared
var body: some Scene {
WindowGroup {
ContentView()
.environment(\.managedObjectContext, persistenceController.container.viewContext)
}
}
}
As we learned in the previous lesson, the first highlighted line creates a shared instance of the PersistenceController
, and the second highlighted line allows us to access the container in sub-views as an environment value.
To fetch data, we use the following code where Person
is our Core Data object:
@FetchRequest(sortDescriptors: []) var people: FetchedResults<Person>
The sortDescriptors
parameter allows us to sort the data, which is something I’m sure we’ll get to in a later lesson.
Now we’re ready to Create, Retrieve, Update, and Delete items in our views.
Create Example:
private func addItem() {
let p = Person(context: viewContext)
p.age = 20
p.name = "Tom"
do {
try viewContext.save() // attempt to save object into core data
}
catch {
// Handle potential error
}
}
The code viewContext.save()
is required to commit all changes to core data. As this has the potential to throw an error, we need to use do-catch
, or just force ignore the error.
To add an item, in this example, we just make a call to our method :
Button(action: addItem) {
Label("Add Item", systemImage: "plus")
}
Retrieve Example:
List {
ForEach(people) { person in
Text(person.name ?? "No name")
}
}
Update Example:
List {
ForEach(people) { person in
Text(person.name ?? "No name")
.onTapGesture{
person.name = "Joe"
try! viewContext.save()
}
}
}
Here, on tapping the person’s name, that name will be changed to “Joe” but it wouldn’t be committed to core data if we didn’t call viewContext.save()
.
Delete Example:
List {
ForEach(people) { person in
Text(person.name ?? "No name")
.onTapGesture{
viewContext.delete(person)
try! viewContext.save()
}
}
}
Again, we need to call viewContext.save()
to make the viewContext.delete()
commit to core data.
There’s a lot of code to wade through when you first set up the project through Xcode, but I think the essentials to handle the basics look to be pretty straightforward. I’m looking forward to the next lessons when we use this in practical examples.