Chơi với SwiftUI và Core Data khiến tôi gặp vấn đề tò mò. Vì vậy, tình hình là như sau:
Tôi có chế độ xem chính "AppView" và chế độ xem phụ có tên "SubView". Chế độ xem SubView sẽ được mở từ chế độ xem AppView nếu tôi nhấp vào nút dấu cộng trong NavigationTitleBar dưới dạng popover hoặc sheet.
@Environment(\.managedObjectContext) var managedObjectContext
@State private var modal: Bool = false
...
Button(action: {
self.modal.toggle()
}) {
Image(systemName: "plus")
}.popover(isPresented: self.$modal){
SubView()
}
Khung nhìn SubView có một hình thức nhỏ với hai đối tượng TextField để thêm tên và họ. Đầu vào của hai đối tượng này được xử lý bởi hai thuộc tính @State riêng biệt. Đối tượng thứ ba trong biểu mẫu này là nút đơn giản, sẽ lưu tên trước và họ vào Thực thể khách hàng đính kèm cho CoreData.
...
@Environment(\.managedObjectContext) var managedObjectContext
...
Button(action: {
let customerItem = Customer(context: self.managedObjectContext)
customerItem.foreName = self.forename
customerItem.surname = self.surname
do {
try self.managedObjectContext.save()
} catch {
print(error)
}
}) {
Text("Speichern")
}
Nếu tôi cố gắng lưu thực thể Khách hàng theo cách này, tôi sẽ gặp lỗi: "nilError", đặc biệt: "Lỗi chưa được giải quyết Tên miền = Foundation._GenericObjCError Code = 0" (null) ", [:]" từ NSError.
Nhưng sau khi nhận ra, khi tôi thêm .environment(\.managedObjectContext, context)
vào lệnh gọi SubView () SubView().environment(\.managedObjectContext, context)
thì nó hoạt động như một bùa mê.
Có ai biết, tại sao tôi cần phải vượt qua ManagedObjectContext lần thứ hai không? Tôi nghĩ rằng tôi chỉ cần vượt qua ManagedObjectContext một lần để sử dụng nó trong toàn bộ hệ thống phân cấp chế độ xem, như trong SceneDelegate.swift:
// Get the managed object context from the shared persistent container.
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
// Create the SwiftUI view and set the context as the value for the managedObjectContext environment keyPath.
// Add `@Environment(\.managedObjectContext)` in the views that will need the context.
let contentView = AppView().environment(\.managedObjectContext, context)
Có phải vì gọi SubView () theo cách này, chế độ xem không phải là một phần của hệ thống phân cấp chế độ xem? Tôi không hiểu điều đó ...