Sunday, July 20, 2014

iOS Tutorial - Part 15 - Add new file Xcode

Add a Model


Video Description 
We talked about communication between View and Controller, now it's time to talk about the Model. In tip calculator app we had only View and Controller. What would be the model in this application? The calculation method could be our Model (updateResult). We can separate this method and add in in a new class.

Add new File in Xcode

In Xcode, open File/New/File..., from the opening window, make sure on left hand side menu select iOS/Cocoa Touch. Select Objective-C Class and hit next. In the next view, in the first field you can specify your file name like TipCalculatorModel. In the second field you specify the subclass of the file that you want to create. Because we want to create a model, we can add NSObject as a subclass of our class. Hit next and then hit create. It adds TipCalculatorModel.h and TipCalculatorModel.m
We move updateResult contents into TipCalculatorModel and modify it like bellow:
- (NSMutableDictionary *)updateResult
{
    float tipAmount = self.tipPercentage * self.billAmount / 100;
    float totalBill = tipAmount + self.billAmount;
    NSMutableDictionary *results = [[NSMutableDictionary alloc] init];
    
    [results setValue:[NSString stringWithFormat:@"Tip amount: %f", tipAmount] forKey:@"tipAmount"];
    [results setValue:[NSString stringWithFormat:@"Total: %f",totalBill] forKey:@"totalBill"];
    
    return results;
}
Because we don't have label we removed all UILabel properties and instead we define tipPercentage and billAmount property in TipCalculatorModel. These two properties will be set from the controller, which is ViewController class. The calculations stays the same. We removed the NSNumber wrappers just to simplify the method, instead we used stringWithFormat method. Last change for TipCalculatorModel is to make this method and two properties public then other classes can see their methods. We do this by adding the properties and the method name in header file (TipCalculatorModel.h) file like bellow:
#import <Foundation/Foundation.h>

@interface TipCalculatorModel : NSObject
@property (nonatomic, assign) int tipPercentage;
@property (nonatomic, assign) float billAmount;
- (NSMutableDictionary *)updateResult;
@end
Then we have to import the Model in our controller, we only import .h file.
#import "TipCalculatorModel.h"
Now we can create a property that is representing our model.
@property (nonatomic, strong) TipCalculatorModel *tipCalculatorModel;
Finally we modify the updateResult method in ViewController like bellow:
- (void)updateResult
{
    self.tipCalculatorModel = [[TipCalculatorModel alloc] init];
    self.tipCalculatorModel.tipPercentage = self.tipPercentageSlider.value;
    self.tipCalculatorModel.billAmount =[self.totalField.text floatValue];
    self.tipAmountLabel.text = [self.tipCalculatorModel.updateResult objectForKey:@"tipAmount"];
    self.resultLabel.text = [self.tipCalculatorModel.updateResult objectForKey:@"totalBill"];
    [self.totalField resignFirstResponder];
}
We create an instance of TipCalculatorModel and then allocate memory and initialize it. We set the tipPercentage property to the slider value. Since we have tipPercentage property in our model so we don't need instance variable tipPercentage in ViewController class.

All of the code for this tutorial

ViewController.m File

#import "ViewController.h"
#import "TipCalculatorModel.h"

@interface ViewController () <UITextFieldDelegate>

@property (nonatomic, strong) TipCalculatorModel *tipCalculatorModel;

@property (weak, nonatomic) IBOutlet UITextField *totalField;
@property (weak, nonatomic) IBOutlet UILabel *tipPercentageLabel;
@property (weak, nonatomic) IBOutlet UISlider *tipPercentageSlider;
@property (weak, nonatomic) IBOutlet UILabel *tipAmountLabel;
@property (weak, nonatomic) IBOutlet UILabel *resultLabel;

@end


@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.totalField.delegate = self;
}


- (IBAction)tipPercentageChanged {
    self.tipPercentageLabel.text = [NSString stringWithFormat:@"Tip Percentage %d%%", self.tipCalculatorModel.tipPercentage];
    [self updateResult];
}

- (IBAction)calculatePressed {
    [self updateResult];
}

- (void)updateResult
{
    self.tipCalculatorModel = [[TipCalculatorModel alloc] init];
    self.tipCalculatorModel.tipPercentage = self.tipPercentageSlider.value;
    self.tipCalculatorModel.billAmount =[self.totalField.text floatValue];
    self.tipAmountLabel.text = [self.tipCalculatorModel.updateResult objectForKey:@"tipAmount"];
    self.resultLabel.text = [self.tipCalculatorModel.updateResult objectForKey:@"totalBill"];
    [self.totalField resignFirstResponder];
}

- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
    [self updateResult];
    return YES;
}

@end

TipCalculatorModel.h

#import <Foundation/Foundation.h>

@interface TipCalculatorModel : NSObject
@property (nonatomic, assign) int tipPercentage;
@property (nonatomic, assign) float billAmount;
- (NSMutableDictionary *)updateResult;
@end

TipCalculatorModel.m

#import "TipCalculatorModel.h"

@interface TipCalculatorModel ()

@end

@implementation TipCalculatorModel


- (NSMutableDictionary *)updateResult
{
    float tipAmount = self.tipPercentage * self.billAmount / 100;
    float totalBill = tipAmount + self.billAmount;
    NSMutableDictionary *results = [[NSMutableDictionary alloc] init];
    
    [results setValue:[NSString stringWithFormat:@"Tip amount: %f", tipAmount] forKey:@"tipAmount"];
    [results setValue:[NSString stringWithFormat:@"Total: %f",totalBill] forKey:@"totalBill"];
    
    return results;
}

@end

Download

Download the Tip Calculator App from here.

No comments:

Post a Comment