Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reflect changes to objects in a relationship in parent object with NSFetchedResultsController

I have two entities event and time. The event entity has a 1 to many relationship to time entities as each event can be performed multiple times. Now I want to display all the events chronologically in a tableView. So I set up a fetchedResultsController to fetch all time objects, sort them according to the start time and display the event information by using the relationship to the event object. So far so good. But now if the user tabs an entry in the table I pass an event object to the detailViewController where the event can be edited.

The problem is that now only the event entity is marked as updated. I found this out by looking at the userInfo directory of the NSManagedObjectDidChange notification. In consequence the delegate methods on the FRC are not fired as no time objects have been changed.

How can I manually mark a time object as changed to make the FRC recognize the changes and update the cells accordingly? I tried firing the KVO methods willChangeValueForKey and didChangeValueForKey but it did not work so far.

Thanks alot Thomas

like image 446
GorillaPatch Avatar asked Oct 24 '10 20:10

GorillaPatch


2 Answers

My model is a little different, but it can easily be translated to your one.
I got a tree-like structure:

  • Element
    • title
    • parent (to-one)
  • Folder : Element
    • children (to-many)
  • File : Element

When a file gets added or deleted, only the first folder in the queue up gets notified about this change. When a file's title changes, not a single folder would get notified. So, what to do?
I tried overriding -willChangeValueForKey: and -didChangeValueForKey: in my Element class.

- (void)willChangeValueForKey:(NSString *)key
{
    [super willChangeValueForKey:key];
    [self.parent willChangeValueForKey:@"children"];
}

- (void)didChangeValueForKey:(NSString *)key
{
    [super didChangeValueForKey:key];
    [self.parent didChangeValueForKey:@"children"];
}

Basically, what this does is forcing the parent folder to update because one of its children changed.
Hope it works for you, too.

like image 132
Christian Schnorr Avatar answered Oct 21 '22 11:10

Christian Schnorr


I'm working through some similar types of updates right now as well. Here's the way I approached the problem.

Let's say we have object A, which relates to object B. B has a property C. We want changes to property C to be reflected in FRCs that use A as the fetched object. What I did to make this happen was to define an accessor to property C from object A:

//A.m
- (void)setC:(int)cValue {
  [self willChangeValueForKey:@"b"];
  self.b.c = cValue
  [self didChangeValueForKey:@"b"];
}

- (int)c {
  return self.b.c;
}

This allowed my cells to update based on FRC callbacks with type NSFetchedResultsChangeUpdate. Hopefully this helps solve your problem.

like image 41
TahoeWolverine Avatar answered Oct 21 '22 11:10

TahoeWolverine