先日の記事で紹介したとおり、CoreDataを使った簡単なTodoアプリを作ってみた。
SwiftUIとCoreDataで一画面のTodoアプリを作ってみた
今回はこのアプリに、追加したタスクを削除してデータベースに保存する機能を実装する方法を紹介する。
コード全文
まずはコード全文を見てもらおう。
import SwiftUI
import CoreData
struct ContentView: View {
@FetchRequest(
sortDescriptors: [NSSortDescriptor(keyPath: \Task.name, ascending: false)],
animation: .default
)
var tasks: FetchedResults<Task>
@Environment(\.managedObjectContext) var viewContext
@State var new = ""
var body: some View {
VStack {
HStack {
TextField("Input here", text: $new)
.textFieldStyle(RoundedBorderTextFieldStyle())
Button(action: {
let newTask = Task(context: self.viewContext)
newTask.name = self.new
do {
try self.viewContext.save()
} catch {
let nsError = error as NSError
fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
}
self.new = ""
}) {
Text("追加")
}
}
List {
ForEach(tasks, id: \.self) { task in
Text("\(task.name!)")
}.onDelete(perform: removeTask)
}
}.padding()
}
private func removeTask(at offsets: IndexSet) {
for index in offsets {
let putTask = tasks[index]
viewContext.delete(putTask)
}
do {
try self.viewContext.save()
} catch {
let nsError = error as NSError
fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
}
}
}
アプリを起動し、あらかじめいくつかのタスクを登録しておく。
CoreDataからデータを削除するメソッドを用意
今回は、データを削除するメソッドを新たに用意する。
private func removeTask(at offsets: IndexSet) {
for index in offsets {
let putTask = tasks[index]
viewContext.delete(putTask)
}
do {
try self.viewContext.save()
} catch {
let nsError = error as NSError
fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
}
}
主な処理は2〜5行目。
offsetsには削除対象の要素番号が入るので、これを使って要素番号に対応するエンティティを削除する。
do〜以降はデータベースへの保存処理。
ListビューのonDeleteメソッドを定義する
あとはListビューのonDeleteメソッドに、用意したremoveTaskを渡せば良い。
List {
ForEach(tasks, id: \.self) { task in
Text("\(task.name!)")
}.onDelete(perform: removeTask)
}
アプリを実行し確認してみよう。
タスクを左へスワイプすると、Deleteボタンが表れる。
Deleteボタンをタップするとリストから削除され、またアプリを再起動しても変更内容が保存されていることが分かる。