在我的例子中,我有一个ContactProfile
视图,我想更新它。我认为最好制作Contact实体的副本,编辑副本,然后将副本的属性"粘贴"回原始实体,然后将其保存在managedObjectcontext
中。
到目前为止,我所掌握的代码只将tempContact
作为原始Contact的参考。这是有道理的,因为原始联系人是由CoreData生成的类,而不是结构。
解决这个问题的最佳方法是什么?还是我想得太多了?@ObservedObject
本身是否足够好,可以进行编辑,因为只有在稍后代码中显式调用private func saveContext()
函数才能将其保存到数据库中?
到目前为止,我有这个代码:
struct ContactProfile: View {
@Environment(.managedObjectContext) private var viewContext
@FetchRequest(
sortDescriptors: [NSSortDescriptor(keyPath: Level.sortOrder, ascending: true)],
animation: .default)
private var levels: FetchedResults<Level>
@ObservedObject var contact: Contact
/// Old code
/// @State private var tempContact: Contact
/// init(contact: Contact){
/// _contact = ObservedObject(initialValue: contact)
/// _tempContact = State(wrappedValue: contact)
/// }
///updated code below:
@State private var tempContact = TempContact(firstName: "", lastName: "", birthDate: Date(), picture: nil)
init(contact: ObservedObject<Contact>) {
_contact = contact
_tempContact = State(initialValue: tempContact)
tempContact.firstName = contact.wrappedValue.firstName ?? ""
tempContact.lastName = contact.wrappedValue.lastName ?? ""
}
///end of updated code
var body: some View {
Form {
Text("@Observed: (contact.firstName ?? "Unknown") (contact.lastName ?? "Unknown")")
Text("@State: (tempContact.firstName ?? "Unknown") (tempContact.lastName ?? "Unknown")")
TextField("Enter name", text: Binding(
get: { self.tempContact.firstName ?? ""},
set: { self.tempContact.firstName = $0 }
)
)
[snipped the rest of the normal view code]
从ContactsList
访问此ContactProfile
,如下所示:
struct ContactsList: View {
@Environment(.managedObjectContext) private var viewContext
@FetchRequest(
sortDescriptors: [NSSortDescriptor(keyPath: Contact.lastName, ascending: true)],
animation: .default
)
private var contacts: FetchedResults<Contact>
var body: some View {
List {
ForEach(contacts) { contact in
NavigationLink(
destination: ContactProfile(contact: contact)) {
HStack (alignment: .firstTextBaseline) {
Text("(contact.firstName ?? "Unknown") (contact.lastName ?? "Unknown")")
Text("((contact.level?.name ?? ""))").font(.caption).foregroundColor(.gray)
}
}
}
.onDelete(perform: deleteContacts)
}
.listStyle(PlainListStyle())
.navigationTitle("Contacts")
.navigationBarItems(trailing: Button(action: addContact) { Image(systemName: "plus") }
)
}
[snip]
处理核心数据中的更新很简单:
- 将CoreData托管对象传递到视图中
- 设置变量以处理数据编辑输入,并将它们设置为CoreData对象值的值,类似于结构,但在视图中为@State
- 验证输入后,将每个属性设置为相应的@State变量,如下所示:[您的实体名称].setValue([您的@State变量],forKey:"[您的属性名称]"(
- 将实体保存在托管对象上下文中,就像创建特定对象时一样
这将更新您的对象,而不是创建一个新对象。