Silver Challenge Solution


#1

It’s interesting to see how different people approach problems and evaluate the various solutions. Here’s mine:

WCOItemStore.h

#import <Foundation/Foundation.h>

@class WCOItem;

@interface WCOItemStore : NSObject

@property (nonatomic, readonly, copy) NSArray *allItems;
@property (nonatomic, readonly, copy) NSArray *allItemsCostingFiftyOrMoreDollars;
@property (nonatomic, readonly, copy) NSArray *allItemsCostingLessThanFiftyDollars;

// A Class method
+ (instancetype)sharedStore;
- (WCOItem *)createItem;

@end

WCOItemStore.m

#import "WCOItemStore.h"
#import "WCOItem.h"

@interface WCOItemStore ()

@property (nonatomic) NSMutableArray *privateItems;

@end

@implementation WCOItemStore

+ (instancetype)sharedStore {
    // Static variables, like global variables, are not destroyed when the
    // method finishes executing. Also, they are not kept on the stack.
    // Also, intial values are set to nil by default.
    static WCOItemStore *sharedStore;
    
    // Do I need to create a sharedStore?
    if (!sharedStore) {
        sharedStore = [[self alloc] initPrivate];
    }
    return sharedStore;
}

// If a programmer calls [[WCOItemStore alloc] init], let him know the
// error of his ways
- (instancetype)init {
    [NSException raise:@"Singleton"
               format:@"Use +[WCOItemStore sharedStore]"];
    return nil;
}

// Here is the real (secret) initializer
- (instancetype)initPrivate {
    self = [super init];
    if (self) {
        _privateItems = [[NSMutableArray alloc] init];
    }
    return self;
}

- (NSArray *)allItems {
    return [self.privateItems copy];
}

- (NSArray *)allItemsCostingFiftyOrMoreDollars {
    NSMutableArray *items = [[NSMutableArray alloc] init];
    for (WCOItem *item in self.privateItems) {
        if (item.valueInDollars >= 50) {
            [items addObject:item];
        }
    }
    return items;
}

- (NSArray *)allItemsCostingLessThanFiftyDollars {
    NSMutableArray *items = [[NSMutableArray alloc] init];
    for (WCOItem *item in self.privateItems) {
        if (item.valueInDollars < 50) {
            [items addObject:item];
        }
    }
    return items;
}

- (WCOItem *)createItem {
    WCOItem *item = [WCOItem randomItem];
    [self.privateItems addObject:item];
    return item;
}

@end

And finally, WCOItemViewController.h

#import "WCOItemsViewController.h"
#import "WCOItemStore.h"
#import "WCOItem.h"

@implementation WCOItemsViewController

// Designated Initializer
- (instancetype)init {
    // Call superclass's designated initializer
    self = [super initWithStyle:UITableViewStyleGrouped];
    if (self) {
        for (int i = 0; i < 5; i++) {
            [[WCOItemStore sharedStore] createItem];
        }
    }
    return self;
}

- (instancetype)initWithStyle:(UITableViewStyle)style {
    
    return [self init];
    
}

- (NSInteger)tableView:(UITableView *)tableView
 numberOfRowsInSection:(NSInteger)section {
    if (section == 0) {
        return [[[WCOItemStore sharedStore] allItemsCostingFiftyOrMoreDollars] count] + 1;
    } else if (section == 1) {
        return [[[WCOItemStore sharedStore] allItemsCostingLessThanFiftyDollars] count] + 1;
    } else {
        return 1;
    }
}

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

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
    if(section == 0) {
        return @"$50 or More";
    } else {
        return @"Less Than $50";
    }
}

- (void)viewDidLoad {
    [super viewDidLoad];
    [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"UITableViewCell"];
}

- (UITableViewCell *)tableView:(UITableView *)tableView
         cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    // Create an instance of UITableViewCell, with a default appearance
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"UITableViewCell"
                                                            forIndexPath:indexPath];
    
    WCOItem *lastItem = [WCOItem alloc];
    lastItem.itemName = @"No more items.";
    lastItem.serialNumber = @"";
    lastItem.valueInDollars = 0;

    NSArray *items = [NSArray array];
    NSMutableArray *tempItems = [NSMutableArray array];
    NSArray *fiftyOrMore = [[WCOItemStore sharedStore] allItemsCostingFiftyOrMoreDollars];
    NSArray *lessThanFifty = [[WCOItemStore sharedStore] allItemsCostingLessThanFiftyDollars];    

    if (indexPath.section == 0) {
        [tempItems addObjectsFromArray:fiftyOrMore];
        [tempItems addObject];
        items = tempItems;
    } else if (indexPath.section == 1){
        [tempItems addObjectsFromArray:lessThanFifty];
        [tempItems addObject];
        items = tempItems;
    }

    WCOItem *item = items[indexPath.row];
    
    // Set the text on the cell with the description of the item that is at the nth index of items,
    // where n = row this cell will appear in on the tableView

    if ([items indexOfObject:item] == [items count] - 1) {
        cell.textLabel.text = [NSString stringWithFormat:@"%@", item.itemName];
    } else {
        cell.textLabel.text = [NSString stringWithFormat:@"$%d - %@", item.valueInDollars, item.description];
    }

    return cell;
}

@end