Search code examples
iosmacoscocoacore-datacocoa-bindings

How to post a notification for a custom Core Data property that is dependent on a relationship?


I have a Client that has a to-many-relationship to Invoice, the property is called invoices. Now I wrote a custom read-only property latestInvoice which I want to observe in my interface:

- (MyInvoice *)latestInvoice
{
  NSArray *invoices = [self valueForKey:@"invoices"];
  NSSortDescriptor *sortDescriptor = [NSSortDescriptor
    sortDescriptorWithKey:@"date" ascending:NO];

  return invoices.count
    ? [invoices sortedArrayUsingDescriptors:@[sortDescriptor]][0]
    : nil;
}

I register Client as an observer for invoices:

- (void)dealloc
{
  [self removeObserver:self forKeyPath:@"invoices"];
}

- (void)registerObservers
{
  [self addObserver:self forKeyPath:@"invoices" options:
    (NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld)
    context:NULL];
}

- (void)awakeFromInsert
{
  [super awakeFromInsert];

  [self registerObservers];
}

- (void)awakeFromFetch
{
  [super awakeFromFetch];

  [self registerObservers];
}

And I manually post change notifications:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object
  change:(NSDictionary *)change context:(void *)context
{
  if ([keyPath isEqualToString:@"invoices"])
  {
    [self willChangeValueForKey:@"latestInvoice"];
    [self didChangeValueForKey:@"latestInvoice"];
  }
}

Is this the right / bug-free / preferred way to do observe Core Data properties that depend on a relationship or do I abuse the framework?


Solution

  • Register latestInvoice as a dependent key of invoices.

    + (NSSet *)keyPathsForValuesAffectingLatestInvoice {
        return [NSSet setWithObjects:@"invoices", nil];
    }