我正在尝试SwiftUI和CoreData。
在ListView中,我通过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
,则会立即显示新条目。这是错误还是我错过了什么?感谢您的帮助。
答案 0 :(得分:1)
已经pbasdf指出了问题确实与NSPredicate
中的UUID比较有关。在比较了UUID而不是字符串之后,一切正常。
将UUID与给定的String进行比较可获取初始数据。可能已在数据库中正确处理了它,但未在“内存中”处理。例如
NSPredicate(format: "%K == %@", #keyPath(Event.task), task.id.uuidString)
适用于删除操作,但不适用于新条目的插入。
要解决此问题,谓词应如下所示
NSPredicate(format: "%K == %@", #keyPath(Event.task), task.id as CVarArg)
另请参阅: https://jisyed.github.io/blog/2018/using-uuids-in-predicates-to-fetch-core-data-entities/