NSFetchedResultsController with relationship not updating

Adam S. picture Adam S. · Sep 23, 2011 · Viewed 7.2k times · Source

Let's say I have two entities, Employee and Department. A department has a to-many relationship with an employee, many employees can be in each department but each employee only belongs to one department. I want to display all of the employees in a table view sorted by data that is a property of the department they belong to using an NSFetchedResultsController. The problem is that I want my table to update when a department object receives changes just like it does if the regular properties of employee change, but the NSFetchedResultsController doesn't seem to track related objects. I've gotten passed this issue partially by doing the following:

for (Employee* employee in department.employees) {
    [employee willChangeValueForKey:@"dept"];
}

/* Make Changes to department object */

for (Employee* employee in department.employees) {
    [employee didChangeValueForKey:@"dept"];
}

This is obviously not ideal but it does cause the employee based FRC delegate method didChangeObject to get called. The real problem I have left now is in the sorting a FRC that is tracking employee objects:

NSEntityDescription *employee = [NSEntityDescription entityForName:@"Employee" inManagedObjectContext:self.managedObjectContext];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"department.someProperty" ascending:NO];

This works great and sorts the employees correctly the first time it's called, the problem is that when I make changes to some property of a department that should change the sorting of my employee table, nothing happens. Is there any nice way to have my employee FRC track changes in a relationship? Particularly I just need some way to have it update the sorting when the sort is based on a related property. I've looked through some similar questions but wasn't able to find a satisfactory solution.

Answer

Marcus S. Zarra picture Marcus S. Zarra · Sep 23, 2011

The NSFetchedResultsController is only designed to watch one entity at a time. Your setup, while it makes sense, it a bit beyond what the NSFetchedResultsController is currently capable of watching on its own.

My recommendation would be to set up your own watcher. You can base it off the ZSContextWatcher I have set up on GitHub, or you can make it even more straightforward.

Basically, you want to watch for NSManagedObjectContextDidSaveNotification postings and then reload your table when one fire that contains your department entity.

I would also recommend filing a rdar with Apple and asking for the NSFetchedResultsController to be improved.