Core data 具有NSPredicate的FetchRequest不会在新条目上更新
我正在试验SwiftUI和CoreData。 在ListView中,我通过Core data 具有NSPredicate的FetchRequest不会在新条目上更新,core-data,swiftui,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
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)")
}
}
}
struct MyList:视图{
var任务:任务
@获取请求
var事件:FetchedResults
@环境(\.managedObjectContext)
var viewContext
初始化(任务:任务){
self.task=任务
self.\u events=FetchRequest(实体:Event.entity(),sortdescriptor:[NSSortDescriptor(keyPath:\Event.timestamp,升序:true)],
谓词:NSPredicate(格式:'%K==%@',#键路径(Event.task),task.id.uuidString),动画:。默认值)
}
var body:一些观点{
VStack{
编辑按钮()
名单{
ForEach(self.events,id:\.self){event in
文本(“\(event.someProperty)”)
}
}.onDelete{索引在
self.events.delete(at:index,from:self.viewContext)
}
}
.航海术语(
尾随:按钮(
行动:{
动画片{
创建(用于:self.task,在:self.viewContext中)
}
}
) {
图像(系统名称:“plus”)
}
)
}
}
扩展事件{
静态func创建(对于任务:任务,在managedObjectContext:NSManagedObjectContext中){
让newEvent=self.init(上下文:managedObjectContext)
newEvent.task=task.id
newEvent.timestamp=Date()
做{
请尝试managedObjectContext.save()
}抓住{
设nserror=错误为nserror
fatalError(“未解决的错误\(nserror),\(nserror.userInfo)”)
}
}
}
扩展集合,其中元素==事件,索引==Int{
func delete(索引处:IndexSet,来自managedObjectContext:NSManagedObjectContext){
index.forEach{managedObjectContext.delete(self[$0])}
做{
请尝试managedObjectContext.save()
}抓住{
设nserror=错误为nserror
fatalError(“未解决的错误\(nserror),\(nserror.userInfo)”)
}
}
}
一切正常。如果我删除一个条目,它会自动从列表中删除
但如果我添加一个条目,它只会在应用程序重启后添加到列表中。如果删除NSPredicate
,则会立即显示新条目。这是一个错误还是我遗漏了什么?感谢您的帮助。已经指出问题确实出在NSPredicate
中的UUID比较上。在比较uuid而不是字符串之后,一切都按预期工作
将UUID与给定字符串进行比较可以获取初始数据。它可能在数据库中得到了正确的处理,但在“内存”处理中没有得到正确的处理。e、 g
NSPredicate(format: "%K == %@", #keyPath(Event.task), task.id.uuidString)
适用于删除操作,但不适用于插入新条目
要解决此问题,谓词应如下所示
NSPredicate(format: "%K == %@", #keyPath(Event.task), task.id as CVarArg)
另见:
您在
事件中执行什么操作。创建?我为事件添加了扩展代码假定Task.id是一个UUID。您设置了newEvent.task=task.id,但谓词指定了task==task.id.uuidString。我的猜测是,在获取过程中,CoreData成功地将UUID连接到它的等效字符串,但上下文的内存处理却没有。如果使用task==task.id作为谓词,它是否工作得更好。比较uuid更有意义。我被误认为参数类型“UUID”不符合预期类型“CVarArg”
错误。但只要有一个演员,一切都会好起来的。谢谢一年后,我发现我的问题在于这个伟大的答案谢谢谢谢非常感谢我真的很高兴谢谢