我如何处理我的CoreData实体的副本,它是@ObservedObject(或者我需要吗?)



在我的例子中,我有一个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]

处理核心数据中的更新很简单:

  1. 将CoreData托管对象传递到视图中
  2. 设置变量以处理数据编辑输入,并将它们设置为CoreData对象值的值,类似于结构,但在视图中为@State
  3. 验证输入后,将每个属性设置为相应的@State变量,如下所示:[您的实体名称].setValue([您的@State变量],forKey:"[您的属性名称]"(
  4. 将实体保存在托管对象上下文中,就像创建特定对象时一样

这将更新您的对象,而不是创建一个新对象。

相关内容

最新更新