I have defined an attribute "id" as UUID in the database. When I want to edit an item, I want it to choose the right item based on the id. But when I edit an item it chooses a random item from the list. I've used a print statement to print the id each time and therefore I've seen that it randomly selects an id and not from the selected item.
import SwiftUI
import CoreData
import Foundation
struct ContentView: View {
@Environment(\.managedObjectContext) private var viewContext
//Abfrage zum Anzeigen
@FetchRequest(sortDescriptors: [NSSortDescriptor(keyPath: \Item.timestamp, ascending: true)],
animation: .default)
//Referenz zum Entity Item
var items: FetchedResults<Item>
@State private var name: String = ""
// Test
@State private var editName = ""
@State private var showEditInput = false
var body: some View {
NavigationView {
VStack{
TextField("Text eingeben", text: $name)
.padding()
Button {
addItem()
} label: {
Text("Save")
}.padding()
List {
ForEach(items, id: \.self) { item in
NavigationLink(destination: ToDo(list:item)) {
HStack {
Text(item.name ?? "Not found")
Button {
self.showEditInput = true
} label: {
Text("Edit")
}.buttonStyle(.bordered)
}.alert("Editieren", isPresented: $showEditInput, actions: {
// Eingabe des neuen Namens
TextField("Neuer Listenname", text: $editName)
Button("Save", action: {
editItem(itemid: item.id!, newName: editName) // Rufe die Edit funktion auf
// self.editName = "" //Resete den Eingabenstring
})
Button("Cancel", role: .cancel, action: {
// self.editName = "" // Resete den Eingabenstring
})
}, message: {
Text("Neuen Namen eingeben")
})
}
}
.onDelete(perform: deleteItems)
}
}
}
}
//MARK: - Hinzufügen der Listen
private func addItem() {
withAnimation {
let newItem = Item(context: viewContext)
newItem.name = name
newItem.id = UUID()
do {
try viewContext.save()
} catch {
// Replace this implementation with code to handle the error appropriately.
// fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
let nsError = error as NSError
fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
}
}
}
private func editItem(itemid id: UUID, newName: String) {
// Fetchrequest um anhand der ID das richtige Item ausfindig zu machen
let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: "Item")
fetchRequest.predicate = NSPredicate(format: "id == %@", id as CVarArg)
do {
let results = try viewContext.fetch(fetchRequest) // Rufe den Fetchrequest auf
let objectToUpdate = results[0] // Nehme das erste
objectToUpdate.setValue(newName, forKey: "name") //Editiere den Key "name" zum übergebenen Wert
print(id)
do {
try viewContext.save() // Speichern
print("Erfolgreich gespeichert!")
} catch let error as NSError {
print("Fehler beim Speichern. \(error), \(error.userInfo)")
}
} catch let error as NSError {
print("Fehler beim Fetchen. \(error), \(error.userInfo)")
}
}
private func deleteItems(offsets: IndexSet) {
withAnimation {
offsets.map { items[$0] }.forEach(viewContext.delete)
do {
try viewContext.save()
} catch {
// Replace this implementation with code to handle the error appropriately.
// fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
let nsError = error as NSError
fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
}
}
}
}