问题
Simply I have an app, and today extension. Also I have two entities: Goal and Service.
@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 }
}
}
When I create service
related to goal
in today extension and update it within an app, updated results are not visible in today extension while are displayed properly in an app. Why?
This is how I create and update record in an extension or in an extension:
MagicalRecord.save({ context in
Service.createOrUpdate(withDuration: duration, date: Date(), identifier: identifier, in: context)
}, completion: { _, error in
//do sth on completion
})
回答1:
The extension and the app are different programs that share some of the same code. So both are creating their own persistentStoreCoordinator and context(s).
Normally in the same app you would have multiple context all attached to the same persistentStoreCoordinator and changes in one would be handled by the notifications that are sent out via notificationCenter and then merged. In this case there are two problems - 1) notificationCenter is not shared between the app and the extension so they can't communicate easily and 2) the context don't share the same persistentStoreCoordinator
so you can't use 'mergeChangesFromContextDidSaveNotification` even if you did pass that information.
I haven't tried this before, but this is what I would try:
- setup some way to trigger that a change occurred. There are many solutions to this.
- setup your
managedObjectContext
(s) to have astalenessInterval
of 0 - when there is a change you have to update your core data. You can do this by calling
refreshObject:mergeChanges:
on all your core data object, or do another fetch. The trick is that you have to have the context fetch from the store and the store to fetch from the file, and not hit any of the caches in the between.
回答2:
Base on @JonRose answer the final solution for my problem was:
fetch records I am interested in, refresh them in the same context where I did fetch them from, and fetch them again:
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]
}
来源:https://stackoverflow.com/questions/41493510/changes-when-record-was-created-in-today-extension-and-updated-in-app-are-not-vi