使用NSPredicate的FetchRequest不会在新条目上更新。

问题描述 投票:1回答:1

我正在用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还是我遗漏了什么?谢谢你的帮助。

core-data swiftui
1个回答
1
投票

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。

© www.soinside.com 2019 - 2024. All rights reserved.