Dalam SwiftUI View
saya memiliki List
berdasarkan pada @FetchRequest
menunjukkan data suatu Primary
entitas dan hubungan yang terhubung Secondary
entitas. The View
dan yang List
diperbarui dengan benar, ketika saya menambahkan baru Primary
entitas dengan entitas sekunder terkait baru.
Masalahnya adalah, ketika saya memperbarui Secondary
item yang terhubung dalam tampilan detail, database akan diperbarui, tetapi perubahannya tidak tercermin dalam Primary
Daftar. Jelas, @FetchRequest
itu 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 Primary
entitas dalam tampilan detail dan perubahan menyebar dengan benar ke tampilan Primary
.
Pertanyaan saya adalah: Bagaimana saya bisa memaksa pembaruan pada semua yang terkait @FetchRequests
dalam 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
?