Trong SwiftUI View
tôi có một List
cơ sở dựa trên việc @FetchRequest
hiển thị dữ liệu của một Primary
thực thể và thực thể thông qua mối quan hệ được kết nối Secondary
. Và View
nó List
được cập nhật chính xác, khi tôi thêm một Primary
thực thể mới với một thực thể thứ cấp mới có liên quan.
Vấn đề là, khi tôi cập nhật Secondary
mục được kết nối trong chế độ xem chi tiết, cơ sở dữ liệu sẽ được cập nhật, nhưng những thay đổi không được phản ánh trong Primary
Danh sách. Rõ ràng, @FetchRequest
không được kích hoạt bởi những thay đổi trong Chế độ xem khác.
Khi tôi thêm một mục mới trong chế độ xem chính sau đó, mục đã thay đổi trước đó cuối cùng sẽ được cập nhật.
Như một giải pháp thay thế, tôi cũng cập nhật thêm một thuộc tính của Primary
thực thể trong chế độ xem chi tiết và các thay đổi lan truyền chính xác đến Primary
Chế độ xem.
Câu hỏi của tôi là: Làm cách nào tôi có thể buộc cập nhật tất cả các @FetchRequests
dữ liệu liên quan đến SwiftUI Core? Đặc biệt, khi tôi không có quyền truy cập trực tiếp vào các thực thể liên quan / @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
?