In this episode, we’ll learn how to delete data.
Let’s start with deletion in the projects (I advise you to take a look at the previous episode because I will start from that code). The first step is to ensure that when we delete a project, we also delete all the pomodoros for that project in cascade. To do that, we need to make some small changes to the ProjectItem
definition.
import Foundation
import SwiftData
@Model
final class ProjectItem: Identifiable {
var name: String
var id = UUID().uuidString
@Relationship(deleteRule: .cascade, inverse: \PomodoroItem.project)
var pomodori = [PomodoroItem]()
init(name: String) {
self.name = name
}
}
We add a @Relationship
attribute for the deletion on the list of pomodoros associated with the project. The deletion will be in cascade, considering the inverse relationship that we have in the PomodoroItem
(where we have project: ProjectItem
) as you can see in the code:
import Foundation
import SwiftData
@Model
final class PomodoroItem {
var start: Date
var end: Date
var project: ProjectItem
var name: String
init(start: Date, end: Date, project: ProjectItem, name: String) {
self.start = start
self.end = end
self.project = project
self.name = name
}
}
Now take a look at the ProjectsView
:
import SwiftUI
import SwiftData
struct ProjectsView: View {
@Environment(\.modelContext) private var modelContext
@Query private var projects: [ProjectItem]
var body: some View {
NavigationStack {
List {
ForEach(projects) { project in
Text(project.name)
}.onDelete(perform: deleteProject)
}
.toolbar {
ToolbarItem {
Button(action: {isPresented = true}) {
Label("Add Project", systemImage: "plus")
}
ToolbarItem(placement: .navigationBarTrailing) {
EditButton()
}
}.sheet(isPresented: $isPresented, content: {
ProjectView()
})
}
}
private func deleteProject(offsets: IndexSet) {
withAnimation {
for index in offsets {
modelContext.delete(projects[index])
}
}
}
}
We added an EditButton
to the toolbar (one of the special buttons in SwiftUI). Tapping on this button will display the buttons to delete the rows. When you tap on one of these buttons, the deleteProjectFunction
is called to delete the project.
The view for the pomodoros is similar:
struct PomodoriView: View {
@Environment(\.modelContext) private var modelContext
@Query private var pomodori: [PomodoroItem]
@State var isPresented = false
var body: some View {
NavigationStack {
List {
ForEach(pomodori) { pomodoro in
Text(pomodoro.name)
}.onDelete(perform: deletePomodoro)
}
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
EditButton()
}
ToolbarItem {
Button(action: {isPresented = true}) {
Label("Add Pomodoro", systemImage: "plus")
}
}
}.sheet(isPresented: $isPresented, content: {
PomodoroView()
})
}
}
private func deletePomodoro(offsets: IndexSet) {
withAnimation {
for index in offsets {
modelContext.delete(pomodori[index])
}
}
}
}
This tutorial may seem short, but I encourage you to experiment with deletion and relationships.
Leave a Reply