@State var documents: [ScanDocument] = []
func loadDocuments() {
guard let appDelegate =
UIApplication.shared.delegate as? AppDelegate else {
return
}
let managedContext =
appDelegate.persistentContainer.viewContext
let fetchRequest =
NSFetchRequest<NSManagedObject>(entityName: "ScanDocument")
do {
documents = try managedContext.fetch(fetchRequest) as! [ScanDocument]
print(documents.compactMap({$0.name}))
} catch let error as NSError {
print("Could not fetch. \(error), \(error.userInfo)")
}
}
In the first view:
.onAppear(){
self.loadDocuments()
}
Now I'm pushing to detail view one single object:
NavigationLink(destination: RenameDocumentView(document: documents[selectedDocumentIndex!]), isActive: $pushActive) {
Text("")
}.hidden()
In RenameDocumentView:
var document: ScanDocument
Also, one function to update the document name:
func renameDocument() {
guard !fileName.isEmpty else {return}
document.name = fileName
try? self.moc.save()
print(fileName)
self.presentationMode.wrappedValue.dismiss()
}
All this code works. This print statement always prints updated value:
print(documents.compactMap({$0.name}))
Here's the list code in main View:
List(documents, id: \.id) { item in
ZStack {
DocumentCell(document: item)
}
}
But where user comes back to previous screen. The list shows old data. If I restart the app it shows new data.
Any help of nudge in a new direction would help.
There is a similar question here: SwiftUI List View not updating after Core Data entity updated in another View, but it's without answers.
NSManagedObject
is a reference type so when you change its properties your documents
is not changed, so state does not refresh view.
Here is a possible approach to force-refresh List when you comes back
@State var documents: [ScanDocument] = []
@State private var refreshID = UUID() // can be actually anything, but unique
List(documents, id: \.id) { item in
ZStack {
DocumentCell(document: item)
}
}.id(refreshID) // << here
NavigationLink(destination: RenameDocumentView(document: documents[selectedDocumentIndex!])
.onDisappear(perform: {self.refreshID = UUID()}),
isActive: $pushActive) {
Text("")
}.hidden()
Alternate: Possible alternate is to make DocumentCell
observe document, but code is not provided so it is not clear what's inside. Anyway you can try
struct DocumentCell: View {
@ObservedObject document: ScanDocument
...
}