Dalam SwiftUI Viewsaya memiliki Listberdasarkan pada @FetchRequestmenunjukkan data suatu Primaryentitas dan hubungan yang terhubung Secondaryentitas. The Viewdan yang Listdiperbarui dengan benar, ketika saya menambahkan baru Primaryentitas dengan entitas sekunder terkait baru.
Masalahnya adalah, ketika saya memperbarui Secondaryitem yang terhubung dalam tampilan detail, database akan diperbarui, tetapi perubahannya tidak tercermin dalam PrimaryDaftar. Jelas, @FetchRequestitu tidak dipicu oleh perubahan di tampilan lain.
Ketika saya menambahkan item baru di tampilan utama setelahnya, item yang sebelumnya diubah akhirnya diperbarui.
Sebagai solusinya, saya juga memperbarui atribut Primaryentitas dalam tampilan detail dan perubahan menyebar dengan benar ke tampilan Primary.
Pertanyaan saya adalah: Bagaimana saya bisa memaksa pembaruan pada semua yang terkait @FetchRequestsdalam Data Inti SwiftUI? Terutama, ketika saya tidak memiliki akses langsung ke entitas terkait / @Fetchrequests?
import SwiftUI
extension Primary: Identifiable {}
// Primary View
struct PrimaryListView: View {
@Environment(\.managedObjectContext) var context
@FetchRequest(
entity: Primary.entity(),
sortDescriptors: [NSSortDescriptor(key: "primaryName", ascending: true)]
)
var fetchedResults: FetchedResults<Primary>
var body: some View {
List {
ForEach(fetchedResults) { primary in
NavigationLink(destination: SecondaryView(primary: primary)) {
VStack(alignment: .leading) {
Text("\(primary.primaryName ?? "nil")")
Text("\(primary.secondary?.secondaryName ?? "nil")").font(.footnote).foregroundColor(.secondary)
}
}
}
}
.navigationBarTitle("Primary List")
.navigationBarItems(trailing:
Button(action: {self.addNewPrimary()} ) {
Image(systemName: "plus")
}
)
}
private func addNewPrimary() {
let newPrimary = Primary(context: context)
newPrimary.primaryName = "Primary created at \(Date())"
let newSecondary = Secondary(context: context)
newSecondary.secondaryName = "Secondary built at \(Date())"
newPrimary.secondary = newSecondary
try? context.save()
}
}
struct PrimaryListView_Previews: PreviewProvider {
static var previews: some View {
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
return NavigationView {
PrimaryListView().environment(\.managedObjectContext, context)
}
}
}
// Detail View
struct SecondaryView: View {
@Environment(\.presentationMode) var presentationMode
var primary: Primary
@State private var newSecondaryName = ""
var body: some View {
VStack {
TextField("Secondary name:", text: $newSecondaryName)
.textFieldStyle(RoundedBorderTextFieldStyle())
.padding()
.onAppear {self.newSecondaryName = self.primary.secondary?.secondaryName ?? "no name"}
Button(action: {self.saveChanges()}) {
Text("Save")
}
.padding()
}
}
private func saveChanges() {
primary.secondary?.secondaryName = newSecondaryName
// TODO: ❌ workaround to trigger update on primary @FetchRequest
primary.managedObjectContext.refresh(primary, mergeChanges: true)
// primary.primaryName = primary.primaryName
try? primary.managedObjectContext?.save()
presentationMode.wrappedValue.dismiss()
}
}
ObservableObject?
