Changes that were created in today's extension and updated in the application are not visible in today's extension
I just have an application, and today the extension. Also I have two objects: Target 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 a service
related goal
in today's extension and update it in the application, the updated results are not displayed in today's extension as long as they are displayed correctly in the application. Why?
This is how I create and update a post 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
})
source to share
An extension and an application are different programs that use the same code. This way both create their own persistentStoreCoordinator and context (s).
Typically, in one application, you have multiple contexts, they are all bound to the same persistent StoreCoordinator, and changes in one will be processed by notifications that are sent via notificationCenter and then merged. In this case, there are two problems: 1) the notificationCenter is not shared with the application and the extension, so they cannot communicate easily, and 2) the context does not use the same persistentStoreCoordinator
, so you cannot use 'mergeChangesFromContextDidSaveNotification` even if you passed this information.
I haven't tried this before, but here's what I would like to try:
- customize how the change is triggered. There are many solutions.
- tune
managedObjectContext
(s) to havestalenessInterval
0 - Whenever a change occurs, you must update your master data. You can do this by calling
refreshObject:mergeChanges:
on your entire main data object, or by doing 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 between.
source to share
Base on @ JonRose's answer for a definitive solution for my problem:
fetch the records that I'm interested in, update them in the same context where I fetched them from , and get 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]
}
source to share