Gold challenge - Class 0 and relationship solutions


#1

Hi everyone,

Here is how I completed the challenge.

Everything takes place in the AssetTypePicker class.

In AssetTypePicker.m I added:

[code]
// Class 0 implementation

  • (NSArray*)getAssetList
    {
    NSManagedObject *assetType = [item assetType];

    NSMutableArray *assetList = [NSMutableArray array];

    for (BNRItem *myItem in [[BNRItemStore sharedStore] allItems]) {
    if ([[myItem assetType] isEqual:assetType]) {
    [assetList addObject:myItem];
    }
    }

    return [NSArray arrayWithArray:assetList];
    }[/code]

Then I added the following methods to get a decent second section:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 2; }

[code]
// I prefered the switch statement to the if statement so that XCode doesn’t warn about return but an if statement is shorter.

  • (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
    {
    switch (section) {
    case 0:
    return @“Asset Type:”;
    break;

      case 1:
          return @"Item(s) for Asset Type:";
          break;
          
      default:
          return @"None";
          break;
    

    }
    }[/code]

Then I modified the “- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath” method like this:

[code]- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@“UITableViewCell”];

if (cell == nil) {
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"UITableViewCell"];
}

if ([indexPath section] == 0) {
    
    NSArray *allAssets = [[BNRItemStore sharedStore] allAssetTypes];
    NSManagedObject *assetType = [allAssets objectAtIndex:[indexPath row]];

    NSString *assetLabel = [assetType valueForKey:@"label"];
    [[cell textLabel] setText:assetLabel];

    if (assetType == [item assetType]) {
        [cell setAccessoryType:UITableViewCellAccessoryCheckmark];
    } else {
        [cell setAccessoryType:UITableViewCellAccessoryNone];
    }
} else if ([indexPath section] == 1) {
    NSArray *assetList = [self getAssetList];
    
    NSString *cellLabel = [[assetList objectAtIndex:[indexPath row]] itemName];
    
    [[cell textLabel] setText:cellLabel];
}
return cell;

}[/code]

At this point the challenge is completed !

But we can have a much cleaner/simpler implementation of the “- (NSArray*)getAssetList” method using the to-many relationship “items” of our BNRAssetType entity:

[code]
// BNRAssetType entity relationship

  • (NSArray*)getAssetList
    {
    return [[[item assetType] valueForKey:@“items”] allObjects];
    }[/code]

The “valueForKey:@“items”” will give you an NSSet that can produce an ordered array of its content, note that as long as you don’t do anything with the NSSet (don’t send any message to it) the set will be “unusable” due to the lazy fetch Joe presented us in the book (you can NSLog() it to see the fault result). As soon as you send the allObject message to the NSSet (that is we use the NSSet) we have everything working as intented and this single line implementation replaces the class 0 one.

Hope this helps.


#2

I haven’t looked at this challenge in a long time but I think this challenge asks us to find all items belonging to a particular asset type. If so, I think what you want to do Is fetch the asset types from he database and then ask that object for all of its items. If this isn’t he case I apologize in advance.

Jeff