I'm dealing with a coredata entity with relationships. The issue is that then I append an item to the children array the UI isn't updated.
var selectedNode : Node
var body: some View {
VStack {
ForEach(selectedNode.childrenArray) { item in
NavigationLink {
Text("Item at \(item.text!)")
} label: {
Text(item.text!)
}
}
}
.toolbar {
ToolbarItem {
Button(action: addItem) {
Label("Add Item", systemImage: "plus")
}
}
}
}
private func addItem() {
withAnimation {
viewContext.performAndWait {
let newItem = Node(context: viewContext)
newItem.text = "Hello worldHello worldHello worldHello worldHello worldHello worldHello worldHello worldHello worldHello worldHello worldHello worldHello world"
newItem.dateAdded = Date()
selectedNode.addToChildren(newItem)
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)")
}
}
}
}
As expected when you populate a View with the coredata array it automatically updates the view with any change in coredata. But since we are not directly using the coredata array to populate the view how should I approach updating the View
.
One possible solution that came to mind was to use predicate to fetch the items that belong to the "children array", so that we can use the coredata array directly to populate the View. But I am so far unable implement this.
CodePudding user response:
All CoreData Objects are ObservableObject
s so they need to be wrapped in @ObservedObject
so the View
can be refreshed when there are changes
@ObservedObject var selectedNode : Node
Also, make sure you are using @FetchRequest
or NSFetchedRequestController
so the store can be observed for changes. NSFetchRequest
does not observe the store.