Update: Filed feedback FB12498822
I'm exploring SwiftData before migrating some existing apps using Core Data. However, I'm not even able to implement this simple action. What I'm trying to accomplish is to let the user choose multiple items from a list, then use a delete button to delete those items from the database. I'm starting off using Xcode's SwiftData project template, then added support for multi-selection and a delete button.
Item.swift
@Model
final class Item {
var title: String
var id: String
init(title: String) {
self.title = title
self.id = UUID().uuidString
}
}
extension Item: Identifiable {}
ContentView.swift
struct ContentView: View {
@Environment(\.modelContext) private var modelContext
@Query private var items: [Item]
@State private var selection: Set<Item.ID> = []
var body: some View {
NavigationView {
List(selection: $selection) {
ForEach(items) { item in
Text(item.title)
}
.onDelete(perform: deleteItems)
}
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
EditButton()
}
ToolbarItem {
Button(action: addItem) {
Label("Add Item", systemImage: "plus")
}
}
ToolbarItem {
Button(action: deleteSelectedItems) {
Label("Delete", systemImage: "trash")
}
}
}
Text("Select an item")
}
}
private func deleteSelectedItems() {
selection
.compactMap { id in
let predicate = #Predicate<Item> { $0.id == id }
let descriptor = FetchDescriptor(predicate: predicate)
let items = try? modelContext.fetch(descriptor)
return items?.first
}
.forEach { modelContext.delete($0) }
}
private func addItem() {
withAnimation {
let newItem = Item(title: "New Item")
modelContext.insert(newItem)
}
}
private func deleteItems(offsets: IndexSet) {
withAnimation {
for index in offsets {
modelContext.delete(items[index])
}
}
}
}
Every time when I tried to delete selected items using the delete button, it crashed on the @PersistedProperty
macro of the id
property of Item
. However, it runs ok if I delete individual item by swiping the row.
Not sure if I'm doing something wrong or is it a bug in the currently beta version of SwiftData. Appreciate if anyone could point me to the right direction.