Using NSTreeController with models that contain different children keypaths

If you use NSTreeController, you usually specify the models’ children keypath through Interface Builder, but what do you do if your models have different keypaths?

The first thing you probably did was define a children alias @property on the managed models. If you tried this, you’d see that the tree will at first draw correctly, but doesn’t refresh when your models update. A quick fix would’ve been to create controllers and observers to manually call [treeController rearrangeobjects]. This isn’t necessary. If setup properly, your NSTreeController can automatically update itself through KVO.

Looking at the NSTreeController reference we see this, “If necessary, you should implement accessor methods in your model classes, that map the child key name to the appropriate class-specific method name.”

How do we do this?

NSKeyValueObserving protocol has a method named +keyPathsForValuesAffecting that we can use to synchronize the the real and alias properties.

Your models end up looking something like:

@interface SomeModel: NSManagedObject
@property (nonatomic, strong)   NSSet *realChildren; // real
@property (nonatomic, readonly) NSSet *children;     // alias

@implementation SomeModel
@dynamic someChildren;                              // real
- (NSSet *)children { return self.realChildren; }   // alias
+ (NSSet *)keyPathsForValuesAffectingChildren {     // synchronize real and alias
    return [NSSet setWithObject:@"realChildren"];