Search code examples
objective-ccore-datansoutlineview

How to use an NSOutlineview with Coredata, grouping entities by their attributes?


I'm fried. I've been stuck on this for two days, googling, and reading, googling and reading.

I have an entity called Session and with an attribute called sessionYear (NSNumber).

I'd like to create an NSOutlineView that will group them by year and then sort them by month, sessionMonth (NSString). Like this:

1984

October
November
December

1989

January
February

2002

March
July
October

I've found lots of information about grouping entities under other entities, and various methods of using array controllers and dictionaries. Unfortunately, much of what I found was outdated or not ostensibly applicable to my situation. I'm new to developing and coredata in general, and would appreciate any guidance on this.

Again, the years are attributes of the entities.

Eventually, I want to be able to click on these entities and populate a tableview. I'd be interested in doing this with bindings if possible, but I've been unable to find solid information. Any help, or links to resources are appreciated.

EDIT:

I've used the NSOutlineViewDelegate approach with the appending four methods. However, now it seems the sessionMonths appear in the view when the year is expanded and then immediately disappear. If another (different) year is expanded all sessionMonths appear where they should and again immediately disappear. I've come so far... for only a glimpse. Any suggestions about where to start?

- (NSInteger)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item {
    if (item == nil) {
        return [savedSessionsOutlineViewData count];
    }

    return [item count];
}

- (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item {
    if (item == nil) {
        item = savedSessionsOutlineViewData;
    }

    if ([item isKindOfClass:[NSMutableArray class]]) {
        return [item objectAtIndex:index];
    }
    else if ([item isKindOfClass:[NSDictionary class]]) {
        NSArray *keys = [item allKeys];
        return [item objectForKey:[keys objectAtIndex:index]];
    }
    return nil;
}

- (id)outlineView:(NSOutlineView *)outline objectValueForTableColumn:(NSTableColumn *)column byItem:(id)item {

    // If the item is a "yearArray" holding sessions.
   if ([item isKindOfClass:[NSMutableArray class]]) {
        NSArray *keys = [savedSessionsOutlineViewData allKeysForObject:item];
        return [keys objectAtIndex:0];
   } else if ([item isKindOfClass:[Session class]]) {
       //NSLog (@"Item returned isKindOfClass:Session");
       return [item valueForKey:@"sessionMonth"];
   }

    return nil;
}
- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item {
    if ([item isKindOfClass:[NSMutableArray class]] || [item isKindOfClass:[NSDictionary class]]) {
        if ([item count] > 0) {
            return YES;
        }
    }

    return nil;
}

Solution

  • In the attributes inspector for the NSOutline view, set the highlight to source list.