我只有一个应用程序,今天扩展。此外,我还有两个实体:目标和服务。
@objc(Goal)
class Goal: NSManagedObject {
@NSManaged var identifier: String
@NSManaged var startDate: Date
@NSManaged var endDate: Date
private var services: [Service] {
let predicate = NSPredicate(format: "date >= %@ && date <= %@", startDate as NSDate, endDate as NSDate)
return Service.mr_findAll(with: predicate) as! [Service]
}
var duration: Int64 {
return services.reduce(0) { $0 + $1.duration }
}
}
当我在今天的扩展程序中创建与service
相关的goal
并在应用内更新时,更新的结果在今天的扩展程序中不可见,同时在应用中正确显示。为什么呢?
这是我在扩展程序或扩展程序中创建和更新记录的方式:
MagicalRecord.save({ context in
Service.createOrUpdate(withDuration: duration, date: Date(), identifier: identifier, in: context)
}, completion: { _, error in
//do sth on completion
})
答案 0 :(得分:4)
扩展程序和应用程序是共享一些相同代码的不同程序。所以两者都在创建自己的 persistentStoreCoordinator和context(s)。
通常在同一个应用程序中,您将有多个上下文全部附加到同一个persistentStoreCoordinator,其中一个中的更改将由通过notificationCenter发送然后合并的通知处理。在这种情况下,有两个问题 - 1)应用程序和扩展程序之间不共享notificationCenter,因此无法轻松进行通信; 2)上下文不共享persistentStoreCoordinator
,因此您可以&即使您确实传递了这些信息,也要使用&#39; mergeChangesFromContextDidSaveNotification`。
我以前没有尝试过这个,但这是我会尝试的:
managedObjectContext
(s)以stalenessInterval
为0 refreshObject:mergeChanges:
来执行此操作,或者执行另一次获取操作。诀窍是你必须从商店和商店获取上下文来从文件中获取,而不是点击中间的任何缓存。答案 1 :(得分:1)
基于@JonRose回答我的问题的最终解决方案是:
获取我感兴趣的记录,在在我从获取的相同上下文中刷新它们,然后再次获取它们:
private var services: [Service] {
let predicate = NSPredicate(format: "date >= %@ && date <= %@", startDate as NSDate, endDate as NSDate)
for service in Service.mr_findAll(with: predicate, in: NSManagedObjectContext.mr_rootSaving())! {
NSManagedObjectContext.mr_rootSaving().refresh(service, mergeChanges: false)
}
return Service.mr_findAll(with: predicate) as! [Service]
}