带有NSPredicate的FetchRequest不会在新条目上更新

时间:2020-05-02 10:19:02

标签: core-data swiftui

我正在尝试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,则会立即显示新条目。这是错误还是我错过了什么?感谢您的帮助。

1 个答案:

答案 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/