Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SwiftUI .onDelete of List view Crashes App

I have a fairly straight forward app built with SwiftUI that is essentially a master detail type. The data is stored in Core Data. Adding and updating records work fine, but the app always crashes when deleting an item from the list view. I am using the .onDelete modifier to do the deletion. I don't receive any error messages - just the thread breaking. The record is indeed deleted, so I'm guessing that the re-rendering of the list view is not receiving updated data.

I may be dreaming, but I'm pretty sure that the delete function worked in the previous two Betas. The app only runs on a device. It will not work in preview nor the simulator.

iOS 13.1, Xcode (11392r), Catalina (19A546d)

Here's the ContentView():

struct ContentView: View {

    @Environment(\.managedObjectContext) var managedObjectContext
    @FetchRequest(fetchRequest: ToDoItem.getAllToDoItems()) var toDoItems: FetchedResults<ToDoItem>

    @State private var newToDoItem = ""

    var body: some View {
        NavigationView {
            List {
                 Section(header: Text("Records")) {
                    ForEach(self.toDoItems) { toDoItem in
                        NavigationLink(destination: EditToDo(toDoItem: toDoItem)) {
                            ToDoItemView(title: toDoItem.title!,
                                         firstName: toDoItem.firstName!,
                                         lastName: toDoItem.lastName!,
                                         //createdAt: "\(toDoItem.createdAt!)")
                                createdAt: self.localTimeString(date: toDoItem.createdAt!)
                                        )
                        }
                    }
                    .onDelete { indexSet in
                        let deleteItem = self.toDoItems[indexSet.first!]
                        self.managedObjectContext.delete(deleteItem)

                        do {
                            try self.managedObjectContext.save()
                        } catch {
                            print(error)
                        }
                    }
                    .onMove(perform: move)
                }
            }
            .navigationBarTitle("Customers")
            .navigationBarItems(trailing: EditButton())
        }
    }

    func move(from source: IndexSet, to destination: Int) {
        print("this is the move method with no actions")
    }

    func localTimeString(date: Date) -> String {
        let formatter = DateFormatter()
        formatter.timeZone = .current
        formatter.dateFormat = "M-d-yyyy HH:mm:ss"
        let returnString = formatter.string(from: date)
        return returnString
    }//localTimeString

}

And the managedObject:

public class ToDoItem : NSManagedObject, Identifiable {
    @NSManaged public var id: UUID
    @NSManaged public var createdAt: Date?
    @NSManaged public var title: String?
    @NSManaged public var firstName: String?
    @NSManaged public var lastName: String?
}

extension ToDoItem {

    static func getAllToDoItems() -> NSFetchRequest<ToDoItem> {
        let request: NSFetchRequest<ToDoItem> = ToDoItem.fetchRequest() as! NSFetchRequest<ToDoItem>
        let sortDescriptor = NSSortDescriptor(key: "createdAt", ascending: true)
        request.sortDescriptors = [sortDescriptor]
        return request
    }
}

Any guidance would be appreciated.

like image 725
JohnSF Avatar asked Aug 30 '19 16:08

JohnSF


1 Answers

This seems hard to believe, but apparently the naming of an attribute in the entity as "id" is the cause of this behavior. I changed the name of the UUID attribute to "myID" and the deletions now work. I updated Xcode to GM seed 2 before making the change (the crash still happened in GM2 before renaming). The list view still does not work at all in the preview, but it does now work in the simulator and with a device.

like image 93
JohnSF Avatar answered Sep 23 '22 19:09

JohnSF