我正在用SwiftUI和CoreData做实验,在一个ListView中,我通过给定的Predicate来显示所有的条目。FetchRequest
:
struct MyList: View {
var task: Task
@FetchRequest
var events: FetchedResults<Event>
@Environment(\.managedObjectContext)
var viewContext
init(task: Task) {
self.task = task
self._events = FetchRequest(entity: Event.entity(), sortDescriptors: [NSSortDescriptor(keyPath: \Event.timestamp, ascending: true)],
predicate: NSPredicate(format: "%K == %@", #keyPath(Event.task), task.id.uuidString), animation: .default)
}
var body: some View {
VStack {
EditButton()
List {
ForEach(self.events, id: \.self) { event in
Text("\(event.someProperty)")
}
}.onDelete { indices in
self.events.delete(at: indices, from: self.viewContext)
}
}
.navigationBarItems(
trailing: Button(
action: {
withAnimation {
Event.create(for: self.task, in: self.viewContext)
}
}
) {
Image(systemName: "plus")
}
)
}
}
extension Event {
static func create(for task: Task, in managedObjectContext: NSManagedObjectContext){
let newEvent = self.init(context: managedObjectContext)
newEvent.task = task.id
newEvent.timestamp = Date()
do {
try managedObjectContext.save()
} catch {
let nserror = error as NSError
fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
}
}
}
extension Collection where Element == Event, Index == Int {
func delete(at indices: IndexSet, from managedObjectContext: NSManagedObjectContext) {
indices.forEach { managedObjectContext.delete(self[$0]) }
do {
try managedObjectContext.save()
} catch {
let nserror = error as NSError
fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
}
}
}
一切正常。如果我删除一个条目,它会自动从列表中删除。
但如果我添加一个条目,它只有在应用程序重新启动后才会添加到列表中。如果我删除 NSPredicate
新条目会立即显示。这是一个bug还是我遗漏了什么?谢谢你的帮助。
有 pbasdf 指出,问题确实出在UUID比较中。NSPredicate
. 在比较UUIDs而不是Strings之后,一切都按预期工作。
将UUID与给定的字符串进行比较后,可以获取初始数据。可能它在数据库中的处理是正确的,但在 "内存 "中的处理就不一样了。
NSPredicate(format: "%K == %@", #keyPath(Event.task), task.id.uuidString)
对删除操作有效,但对插入新条目无效。
为了解决这个问题,谓词应该是这样的
NSPredicate(format: "%K == %@", #keyPath(Event.task), task.id as CVarArg)
另见。https:/jisyed.github.ioblog2018using-uuids-in-predicates-to-fetch-core-data-entities。