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.
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)")
}
}
}