My Silver Challenge Solution


#1

Here is the code from my Silver Challenge solution. Basically, I added a navigation + button to the assetpicker view. This pushes a new View Controller onto the screen called AddAssetTypeViewController. This was created with a xib file as well as and h & m. The xib has a UIText Field and a button named AddAssetType. The AddAssetType then sends a message to BNRItemStore to a new method called addNewAssetTypeWithType:. If you have any suggestions or comments let me know.

AssetTypePicker.h

//
//  AssetTypePicker.h
//  Homepwner
//
//  Created by Jeff Garrett on 6/23/13.
//  Copyright (c) 2013 JeffGarrett. All rights reserved.
//

#import <Foundation/Foundation.h>

@class BNRItem;

@interface AssetTypePicker : UITableViewController
{   
}

@property (nonatomic, strong) BNRItem *item;

-(void)addAssetType;

@end

AssetTypePicker.m

//
//  AssetTypePicker.m
//  Homepwner
//
//  Created by Jeff Garrett on 6/23/13.
//  Copyright (c) 2013 JeffGarrett. All rights reserved.
//

#import "AssetTypePicker.h"
#import "BNRItemStore.h"
#import "BNRItem.h"
#import "AddAssetTypeViewController.h"

@implementation AssetTypePicker

@synthesize item;

-(id)init
{
    self = [super initWithStyle:UITableViewStyleGrouped];
    
    if (self)
    {
        UIBarButtonItem *addNav = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd
                                                                                                                       target:self
                                                                                                                       action:@selector(addAssetType)];
        [[self navigationItem] setRightBarButtonItem:addNav];
    }
    
    return self;
}

-(void)viewWillAppear:(BOOL)animated
{
    [[self tableView] reloadData];
}

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

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [[[BNRItemStore sharedStore] allAssetTypes] count];
}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)ip
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"UITableViewCell"];
    
    if (cell == nil)
    {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"UITableViewCell"];
    }
    
    NSArray *allAssets = [[BNRItemStore sharedStore] allAssetTypes];
    NSManagedObject *assetType = [allAssets objectAtIndex:[ip row]];
    
    NSString *assetLabel = [assetType valueForKey:@"label"];
    [[cell textLabel] setText:assetLabel];
    
    if (assetType == [item assetType])
    {
        [cell setAccessoryType:UITableViewCellAccessoryCheckmark];
    }
    else
    {
        [cell setAccessoryType:UITableViewCellAccessoryNone];
    }
    
    return cell;
}

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)ip
{
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:ip];
    
    [cell setAccessoryType:UITableViewCellAccessoryCheckmark];
    
    NSArray *allAssets = [[BNRItemStore sharedStore] allAssetTypes];
    NSManagedObject *assetType = [allAssets objectAtIndex:[ip row]];
    [item setAssetType:assetType];
    
    [[self navigationController] popViewControllerAnimated:YES];
}

-(void)addAssetType
{
    //This method is used to  call the AddAssetTypeViewContoller to add another asset type.
    AddAssetTypeViewController *addAssetType = [[AddAssetTypeViewController alloc] init];
        
    [[self navigationController] pushViewController:addAssetType animated:YES];
}
@end

AddAssetTypeViewController.h

//
//  AddAssetTypeViewController.h
//  Homepwner
//
//  Created by Jeff Garrett on 6/25/13.
//  Copyright (c) 2013 JeffGarrett. All rights reserved.
//

#import <UIKit/UIKit.h>
#import "AssetTypePicker.h"
#import "BNRItemStore.h"

@interface AddAssetTypeViewController : UIViewController
{
    __weak IBOutlet UITextField *newAssetType;
}

- (IBAction)addAssetType:(UIButton *)sender;
@end

AddAssetTypeViewController.m

//
//  AddAssetTypeViewController.m
//  Homepwner
//
//  Created by Jeff Garrett on 6/25/13.
//  Copyright (c) 2013 JeffGarrett. All rights reserved.
//

#import "AddAssetTypeViewController.h"

@interface AddAssetTypeViewController ()

@end

@implementation AddAssetTypeViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) 
    {
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
}

- (IBAction)addAssetType:(UIButton *)sender
{
    NSString *newAssetTypeString = newAssetType.text;
    [[BNRItemStore sharedStore] addNewAssetTypeWithType:newAssetTypeString];
    
    [[self view] endEditing:YES];
    
    [[self navigationController] popViewControllerAnimated:YES];
}
@end

Relevant declaration code from BNRItemStore.h

-(void)addNewAssetTypeWithType:(NSString *)typeString;

Declared code from BNRItemStore.m

-(void)addNewAssetTypeWithType:(NSString *)typeString
{
    if (!allAssetTypes)
    {
        NSFetchRequest *request = [[NSFetchRequest alloc] init];
        NSEntityDescription *e = [[model entitiesByName] objectForKey:@"AssetType"];
        
        [request setEntity:e];
        
        NSError *error;
        NSArray *result = [context executeFetchRequest:request error:&error];
        if (!result)
        {
            [NSException raise:@"Fetch failed" format:@"Reason: %@", [error localizedDescription]];
        }
        allAssetTypes = [result mutableCopy];
    }
    
    NSManagedObject *type;
    type = [NSEntityDescription insertNewObjectForEntityForName:@"AssetType"
                                                          inManagedObjectContext:context];
    [type setValue:typeString forKey:@"label"];
    [allAssetTypes addObject:type];
}

#2

Nice, Jeff. Here’s my Ch 16 Silver solution. I decided to put a textfield in the nav bar when adding a new asset type. It seems to feel ok.

[code]//
// AssetTypePicker.h
// Homepwner
//
// Created by Kevin Taniguchi on 7/6/13.
// Copyright © 2013 com.bignerdranch. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

@class BNRItem;
@interface AssetTypePicker : UITableViewController
{
NSMutableArray *allAssetTypes;
UITextField *assetField;
}

@property (nonatomic, strong) BNRItem *item;
-(void)newAsset:(id)sender;
@end[/code]

[code]//
// AssetTypePicker.m
// Homepwner
//
// Created by Kevin Taniguchi on 7/6/13.
// Copyright © 2013 com.bignerdranch. All rights reserved.
//

#import “AssetTypePicker.h”
#import “BNRItemStore.h”
#import “BNRItem.h”

@implementation AssetTypePicker
@synthesize item;

// START CH 16 SILVER CHALLENGE: add new asset types
// add nav bar button item for adding new asset types
-(id)init{
self = [super initWithStyle:UITableViewStyleGrouped];

if(self){
    UINavigationItem *n = [self navigationItem];
    [n setTitle:@"Asset Types"];
UIBarButtonItem *newAsset = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(newAsset:)];
[[self navigationItem]setRightBarButtonItem];
}
return self;

}

// upon pressing the add button, create a textfield in the nav bar to enter in new asset type text
-(void)newAsset:(id)sender{
assetField = [[UITextField alloc]initWithFrame:CGRectMake(10, 200, 300, 31)];
[assetField setBorderStyle:UITextBorderStyleRoundedRect];
[assetField setPlaceholder:@“Enter New Asset Type”];
[assetField setClearsOnBeginEditing:YES];
[assetField setReturnKeyType:UIReturnKeyDone];
[assetField setDelegate:self];
[[self navigationItem]setTitleView:assetField];
}

// when user presses done, a new cell with the new asset type is made

  • (BOOL)textFieldShouldReturn:(UITextField *)tf{
    NSString *s = [assetField text];
    [[BNRItemStore sharedStore]newAssetType:s];
    [[self tableView]reloadData];
    [assetField resignFirstResponder];
    return NO;
    }

// refresh with new cell rows
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear];
[[self tableView] reloadData];
}
// END CH 16 SILVER CHALLENGE: add new asset types[/code]

// // BNRItemStore.m // Homepwner // // Created by Kevin Taniguchi on 6/25/13. // Copyright (c) 2013 com.bignerdranch. All rights reserved. // // ******* // // take in new asset name from assetField and add new assetType object to the database -(NSArray*)newAssetType:(NSString*)newAssetName{ NSManagedObject *newAssetType; newAssetType = [NSEntityDescription insertNewObjectForEntityForName:@"BNRAssetType" inManagedObjectContext:context]; [newAssetType setValue:newAssetName forKey:@"label"]; [allAssetTypes addObject:newAssetType]; return allAssetTypes; }