I'm reading a CoreData database in a WatchKit extension, and changing the store from the parent iPhone application. I'd like to use NSFetchedResultsController to drive changes to the watch UI, but NSFetchedResultsController in the extension doesn't respond to changes made to the store in the parent application. Is there any way to get the secondary process to respond to changes made in the first process?
4 Answers
Some things to try/consider:
Do you have App Groups enabled? If so, is your data store in a location shared between your host app and the extension? If so does deleting the cached data, as referenced here help?
-
Thanks for your reply. They are sharing an app group, and there is a Darwin notification being sent when changes occur. But clearing the cache when that notification arrives, or clearing the cache and performing a new fetch are not causing the delegate functions to fire. – Colin Cornaby Apr 28 '15 at 18:18
Read this answer to very similar question: https://stackoverflow.com/a/29566287/1757229
Also make sure you set stalenessInterval
to 0.
I faced the same problem. My solution applies if you want to update the watch app on main app updates, but it could be easily extended to go both ways.
Note that I'm using a simple extension on NSNotificationCenter in order to be able to post and observe Darwin notification more easily.
1. Post the Darwin notification
In my CoreData store manager, whenever I save the main managed object context, I post a Darwin notification:
notificationCenter.addObserverForName(NSManagedObjectContextDidSaveNotification, object: self.managedObjectContext, queue: NSOperationQueue.mainQueue(), usingBlock: { [weak s = self] notification in
if let moc = notification.object as? NSManagedObjectContext where moc == s?.managedObjectContext {
notificationCenter.postDarwinNotificationWithName(IPCNotifications.DidUpdateStoreNotification)
}
})
2. Listen for the Darwin notification (but only on Watch)
I listen for the same Darwin notification in the same class, but making sure I am on the actual watch extension (in order to avoid to refresh the context that just got updated). I'm not using a framework (must target also iOS 7) so I just added the same CoreDataManager on both main app and watch extension. In order to determine where I am, I use a compile time flag.
#if WATCHAPP
notificationCenter.addObserverForDarwinNotification(self, selector: "resetContext", name: IPCNotifications.DidUpdateStoreNotification)
#endif
3. Reset context
When the watch extension receives the notification, it resets the MOC context, and sends an internal notification to tell FRCs to update themselves. I'm not sure why, but it wasn't working fine without using a little delay (suggestions are welcome)
func resetContext() {
self.managedObjectContext?.reset()
delay(1) {
NSNotificationCenter.defaultCenter().postNotificationName(Notifications.ForceDataReload, object: self.managedObjectContext?.persistentStoreCoordinator)
}
}
4. Finally, update the FRCs
In my case, I was embedding a plain FRC in a data structure so I added the observer outside of the FRC scope. Anyway you could easily subclass NSFetchedResultsController and add the following line in its init method (remember to stop observing on dealloc)
NSNotificationCenter.defaultCenter().addObserver(fetchedResultController, selector: "forceDataReload:", name: CoreDataStore.Notifications.ForceDataReload, object: fetchedResultController.managedObjectContext.persistentStoreCoordinator)
and
extension NSFetchedResultsController {
func forceDataReload(notification: NSNotification) {
var error : NSError?
if !self.performFetch(&error) {
Log.error("Error performing fetch update after forced data reload request: \(error)")
}
if let delegate = self.delegate {
self.delegate?.controllerDidChangeContent?(self)
}
}

- 3,443
- 20
- 24
At WWDC ‘17, Apple introduced a number of new Core Data features, one of which is Persistent History Tracking or NSPersistentHistory. But as of the time of writing, its API is still undocumented. Thus, the only real reference is the What’s New in Core Data WWDC session.
More info and an example here

- 26,330
- 7
- 115
- 133