Deleting CoreData Item which is also an @ObservedObject in DetailView causing App Crash in Swift 5

444 Views Asked by At

I am currently working with SwiftUI and CoreData.

Situation: I have a User Detail View with a Delete Button. When pressed, the Core Data Entry of the User is getting deleted and the App Navigation goes back to the Root Navigation View, which is a List of all Users.

Problem: Every Time the Delete Button is clicked the App crashes with the following Error Message:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[User timeCreated]: unrecognized selector sent to instance 0x2802ffa40'

My Guess: I guess the Problem has something to do with the Fact, that I use a @ObservedObject Property Wrapper for the User Object (look Code below). This is also updating on Delete which obviously causes some Problems.

import SwiftUI

struct UserView: View {
    @FetchRequest(sortDescriptors: [NSSortDescriptor(keyPath: \User, ascending: false)], animation: .default) private var users: FetchedResults<User>
    
    var body: some View {
        NavigationView {
            List {
                ForEach(users) { user in
                    NavigationLink(destination: UserDetailView(user: user)) {
                        Text(user.name)
                    }
                }
            }
        }
    }
}

struct UserDetailView: View {
    @Environment(\.managedObjectContext) var context
    @Environment(\.presentationMode) var mode: Binding<PresentationMode>
    
    @ObservedObject var user: User
    
    var body: some View {
        Button(action: { deleteUser() }) {
            Text("Delete")
        }
    }
    
    private func deleteUser() {
        context.delete(user)
            
        do {
            try context.save()
            
            // Navigate Back to List View
            self.mode.wrappedValue.dismiss()
                
        } catch let error as NSError {
            print("Error deleting Item from Core Data: \(error), \(error.userInfo)")
        }
    }
}

Question: How can I delete the User and return to the Root List View without an App Crash? (Note: Obviously the most easiest Solution would be to make user a normal Property, however, I need the automatic Update Behaviour since there is also a Update User View which may change some of the Content)

Thanks for your Help.

1

There are 1 best solutions below

7
On BEST ANSWER

I'm not sure that the issue is in provided code... but try the following (not tested - just idea - defer deleting):

private func deleteUser() {
    mode.wrappedValue.dismiss()

    DispatchQueue.main.async {
      context.delete(user)
      do {
        try context.save()
      } catch let error as NSError {
          print("Error deleting User from Core Data: \(error), \(error.userInfo)")
      }
   }
}