Operation Models Slides

Embed Size (px)

Citation preview

  • 7/30/2019 Operation Models Slides

    1/147

  • 7/30/2019 Operation Models Slides

    2/147

    LEVEL 1

  • 7/30/2019 Operation Models Slides

    3/147

    INSTAPHOTO - WHERE WE LEFT IT

  • 7/30/2019 Operation Models Slides

    4/147

    WHY MODELS?

    Controllers tell Views how

    to display data

    Views display app data

    Models handle app data

    from Models

    Models make it easy to organize and store data in an a

  • 7/30/2019 Operation Models Slides

    5/147

    DATA IN INSTAPHOTO - THE CURRENT APPROA

    Controllers drawing Views using data from a Controller

    data passed whencell tapped

    Thats no g

    FeedTableVC PhotoVC

    View View

  • 7/30/2019 Operation Models Slides

    6/147

    DATA IN INSTAPHOTO - THE MVC WAY

    Controllers drawing Views using data from a Model

    Controller

    asks for data

    Model provides

    data object

    model instancepassed when celltapped

    FeedTableVC PhotoVC

    View View

    Model

  • 7/30/2019 Operation Models Slides

    7/147

    CREATING A MODEL CLASS IN XCODE

  • 7/30/2019 Operation Models Slides

    8/147

    CLASS HIERARCHY OF A MODEL

    NSObject is the base parent Class of almost everything

    @interface Place : NSObject

    NSObject

    UIResponder

    UIViewController

    UITabBarController UINavigationController

    Place

    Class Name Parent Class

    Model is a subclassof NSObject

  • 7/30/2019 Operation Models Slides

    9/147

    PLANET HIG

    Straight to the TOP

    of the APP STORE!

  • 7/30/2019 Operation Models Slides

    10/147

    PLANET HIG CLASS STRUCTURE

    CityViewControlPlaceTableViewController InterestingPlacesTableViewController

    AppDelegate

  • 7/30/2019 Operation Models Slides

    11/147

    PLACE MODEL @INTERFACE AND @IMPLEMEN

    Place.h

    Place.m

    singular name, not plu

    #import"Place.h"

    @implementation Place

    @end

    #import

    @interface Place : NSObject

    @end

  • 7/30/2019 Operation Models Slides

    12/147

    DECLARING PLACE MODEL @PROPERTY VARIA

    #import

    @end

    Place.h

    @interface Place : NSObject

    @property (strong, nonatomic)NSString*name;

    @property (strong, nonatomic)NSString*description;NSStr

  • 7/30/2019 Operation Models Slides

    13/147

    IMPLEMENTING INIT IN THE PLACE MODEL

    #import"Place.h"

    @end

    Place.m

    @implementation Place

    selfrefers to an instance of this Class (Place)superrefers to the parent Class (NSObject)

    NSOb

    Place

    -(id)i[super init]

    self supe

    - (id)init {

    self = [superinit];

    return self;

    }

  • 7/30/2019 Operation Models Slides

    14/147

    MODEL OBJECT INSTANTIATION

    PlaceViewController.m

    console output

    > name is: Taco Cantina> description is: Tasty tacos.

    Access valuesor message pa

    Place *aPlace = [[Place alloc] init];

    aPlace.name = @"Taco Cantina";aPlace.description = @"Tasty tacos.";

    NSLog(@"name is: %@", [aPlace name]);NSLog(@"description is: %@", aPlace.description);

  • 7/30/2019 Operation Models Slides

    15/147

    INSTANTIATE MULTIPLE OBJECTS WITH ONE M

    PlaceViewController.m

    Place *placeOne = [[Place alloc] init];

    Place *placeTwo = [[Place alloc] init];Place *placeThree = [[Place alloc] init];

    @"Taco Cantina"

    @"Tasty tacos."

    @"Fish Town"

    @"Scrumptious sushi."

    @"Envy Labs"

    @"Enviable educators."

    placeOne.name =placeTwo.name =placeThree.name =

    placeOne.description =placeTwo.description =placeThree.description =

    ;;;

    ;;;

    Thats a l

    of repeti

  • 7/30/2019 Operation Models Slides

    16/147

    OBJECT INSTANTIATION WITH A CONVENIENCE INIT

    PlaceViewController.m

    Place *placeOne = [[Place alloc] init

    Place *placeTwo = [[Place alloc] init

    Place *placeThree = [[Place alloc] init

    ];

    @"Taco Cantina"

    @"Fish Town"

    @"Envy Labs"

    @"Tasty tacos."

    @"Scrumptious sushi

    @"Enviable educat

    initWithName:description: is called a convenience initiali

    WithName:

    description:

    WithName:description:

    WithName:description:

  • 7/30/2019 Operation Models Slides

    17/147

    DECLARING A CONVENIENCE INITIALIZER

    @end

    Place.h

    - (id)initWithName:(NSString *)aName

    description:(NSString *)aDescription;

    #import

    @interface Place : NSObject

    @property (strong, nonatomic)NSString*name;

    @property (strong, nonatomic)NSString*description;

  • 7/30/2019 Operation Models Slides

    18/147

    IMPLEMENTING A CONVENIENCE INITIALIZER

    Place.m

    {

    PlaceViewController.m

    Place *placeOne = [[Place alloc] initWithName:@"Taco Cantina"

    description:@"Tasty tacos."];

    local argumentsmodel properties

    verify [superintrying to set prop

    - (id)initWithName:(NSString *)aName

    description:(NSString *)aDescription

    self = [superinit];if(self) {

    self.name = aName;self.description = aDescription;

    }return self;

    }

    THE PROBLEM WITH INIT

  • 7/30/2019 Operation Models Slides

    19/147

    Place *placeOne = [[Place alloc] initWithName:@"Taco Cantina"

    description:@"Tasty tacos."];

    THE PROBLEM WITH INIT

    PlaceViewController.m

    Place *placeTwo = [[Place alloc] init];

    NSLog(@"placeOne name: %@", placeOne.name);

    NSLog(@"placeTwo name: %@", placeTwo.name);

    Console output> placeOne name: Taco Cantina

    > placeTwo name: nil

    What COUNT

    NIL IN????

    CONVERTING TO A DESIGNATED INITIALIZER

  • 7/30/2019 Operation Models Slides

    20/147

    CONVERTING TO A DESIGNATED INITIALIZER

    Place.m

    @end

    - (id)initWithName:(NSString *)aName

    description:(NSString *)aDescription {

    self = [superinit];

    if(self) { self.name = aName; self.description = aDescription;

    }return self;

    }

    - (id)init {self = [self initWithName:@"defaultName"

    description:@"defaultDescription"];return self;

    }

    USING A DESIGNATED INITIALIZER

  • 7/30/2019 Operation Models Slides

    21/147

    USING A DESIGNATED INITIALIZER

    PlaceViewController.m

    Console output

    > placeOne name: Taco Cantina> placeTwo name: defaultName

    init triggers the designated initializerinitWithName:description:

    Place *placeOne = [[Place alloc] initWithName:@"Taco Cantina"

    description:@"Tasty tacos."];Place *placeTwo = [[Place alloc] init];

    NSLog(@"placeOne name: %@", placeOne.name);

    NSLog(@"placeTwo name: %@", placeTwo.name);

    MODEL CONVENTIONS

  • 7/30/2019 Operation Models Slides

    22/147

    MODEL CONVENTIONS

    @property memory management

    @property (strong, nonatomic);

    Arguments should start with a, an, or the

    - (id)initWithCity:(NSString *)city address:(NSString *)address

    - (id)initWithCity:(NSString *)aCity address:(NSString *)anAddres

    Long method names on multiple lines lined up by colons

    - (id)initWithCity:(NSString *)aCity address:(NSString *)anAddres

    - (id)initWithCity:(NSString *)aCity address:(NSString *)anAddress

  • 7/30/2019 Operation Models Slides

    23/147

    LEVEL 2

    CITYVIEWCONTROLLER IN PLANET HIG

  • 7/30/2019 Operation Models Slides

    24/147

    CITYVIEWCONTROLLER IN PLANET HIG

    ViewCityViewController

    nameLabel stateLabel p

    Lets see where this city data comes f

    FETCHING THE CITY DATA FOR PLANET HIG

  • 7/30/2019 Operation Models Slides

    25/147

    FETCHING THE CITY DATA FOR PLANET HIG

    2 NSStrings

    1 NSNumber

    1 NSDictionary containing:

    CityViewController.h

    @property (strong, nonatomic) NSDictionary *cityData;

    http://example.com/cityData.json

    old way

    {

    "name": "Orlando","state": "Florida",

    "population": 238300

    }

    FETCHING CITYDATA JSON WITH AFNETWORK

    http://remote.com/cityData.JSONhttp://remote.com/cityData.JSON
  • 7/30/2019 Operation Models Slides

    26/147

    FETCHING CITYDATA.JSON WITH AFNETWORK

    self.cityData = JSON;

    NSLog(@"NSError: %@",error.localizedDescription);

    }];

    [operation start];

    AFJSONRequestOperation *operation = [AFJSONRequestOperationJSONRequestOperationWithRequest:requestsuccess:^(NSURLRequest *request, NSHTTPURLResponse *response, id

    } failure:^(NSURLRequest *request, NSHTTPURLResponse *response,

    NSError *error, id J

    [self dataRetrieved];

    CityViewController.m

    NSURL *url = [[NSURL alloc] initWithString:@"http://codeschool.com/c

    NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url];

    USING THE JSON RESPONSE IN DATARETRIEVED

    http://codeschool.com/placeData.jsonhttp://codeschool.com/placeData.json
  • 7/30/2019 Operation Models Slides

    27/147

    USING THE JSON RESPONSE IN DATARETRIEVED

    self.cityData = JSON;

    AFJSONRequestOperation *operation = [AFJSONRequestOperation

    JSONRequestOperationWithRequest:requestsuccess:^(NSURLRequest *request, NSHTTPURLResponse *response, id

    }[self dataRetrieved];

    ...

    - (void)dataRetrieved {

    NSLog(@"City name is: %@", self.cityData[@"name"]);NSLog(@"City state is: %@", self.cityData[@"state"]);

    NSLog(@"City population is: %@", self.cityData[@"population"]);

    }

    This seems like a go

    place For a Model

    CityViewController.m

    LETS CREATE THE CITY MODEL

  • 7/30/2019 Operation Models Slides

    28/147

    LET S CREATE THE CITY MODEL

    #import

    @interface City : NSObject

    @property (strong, nonatomic)NSString*name;@property (strong, nonatomic)NSString*state;

    @property (strong, nonatomic)NSNumber*population;

    @end

    City.h

    #import"City.h"@implementation City

    - (id)init {

    self = [superinit];

    return self;

    }

    @end

    City.m

    PUTTING THE JSON RESPONSE IN A MODEL

  • 7/30/2019 Operation Models Slides

    29/147

    PUTTING THE JSON RESPONSE IN A MODEL

    self.city.name = JSON[@"name"];

    AFJSONRequestOperation *operation = [AFJSONRequestOperationJSONRequestOperationWithRequest:requestsuccess:^(NSURLRequest *request, NSHTTPURLResponse *response, id J

    }

    [self dataRetrieved];

    ...

    self.city.state = JSON[@"state"];

    self.city.population = JSON[@"population"];

    CityViewController.h

    @property (strong, nonatomic) City *city;

    self.city = [[City alloc] init];

    CityViewController.m

    Seems like we can improv

    #import"City.h"

    NSLog(@"City name is: %@", self.city.name);

    NSLog(@"City state is: %@", self.city.state);

    NSLog(@"City population is: %@", self.city.population);

    - (void)dataRetrieved {

    }

    INITIALIZING MODEL DATA IN A CONTROLLER

  • 7/30/2019 Operation Models Slides

    30/147

    INITIALIZING MODEL DATA IN A CONTROLLER

    Controller is respfetching data, no

    PROBLEM

    View

    City

    CityViewController

    INITIALIZING MODEL DATA IN A MODEL

  • 7/30/2019 Operation Models Slides

    31/147

    INITIALIZING MODEL DATA IN A MODEL

    Model is responsi

    fetching data, notController.

    initWithJSON:

    SOLUTION

    convenienceinitializer

    I love convenien

    solutions

    City

    View

    CityViewController

    DECLARING AN INITWITHJSON CONVENIENCE INITIALIZER

  • 7/30/2019 Operation Models Slides

    32/147

    DECLARING AN INITWITHJSON CONVENIENCE INITIALIZER

    City.h

    - (id)initWithJSON;

    #import@interface City : NSObject

    @property (strong, nonatomic)NSString*name;

    @property (strong, nonatomic)NSString*state;

    @property (strong, nonatomic)NSNumber*population;

    @end

    IMPLEMENTING INITWITHJSON IN THE CITY M

  • 7/30/2019 Operation Models Slides

    33/147

    IMPLEMENTING INITWITHJSON IN THE CITY M

    #import"City.h"

    @end

    City.m

    @implementation City

    - (id)init { self = [superinit];

    return self;}

    AFJSONRequestOperation *operation = [AFJSONRequestOperation

    self = [superinit];if(self) {

    } return self;}

    - (id)initWithJSON {

    SETTING MODEL PROPERTIES USING INITWITH

  • 7/30/2019 Operation Models Slides

    34/147

    SETTING MODEL PROPERTIES USING INITWITH

    City.m

    NSLog(@"NSError: %@",error.localizedDescription);

    }];

    [operation start];

    success:^(NSURLRequest *request, NSHTTPURLResponse *respon

    failure:^(NSURLRequest *request, NSHTTPURLResponse *responsNSError *error

    }

    self.name = JSON[@"name"];

    self.state = JSON[@"state"]; self.population = JSON[@"population"];

    AFJSONRequestOperation *operation = [AFJSONRequestOperationJSONRequestOperationWithRequest:request

    self = [superinit];

    if(self) {

    } return self;

    }

    - (id)initWithJSON {

    TESTING INITWITHJSON

  • 7/30/2019 Operation Models Slides

    35/147

    TESTING INITWITHJSON

    self.city = [[Cityalloc] initWithJSON];

    NSLog(@"state is: %@", self.city.state);

    NSLog(@"population is is: %d", self.city.population);

    CityViewController.m

    CityViewController.h

    #import"City.h"

    @property (strong, nonatomic) City *city;

    nil

    nil

    What In the NIL Is GOING ON?

    WHY INITWITHJSON ALONE IS NOT ENOUGH

  • 7/30/2019 Operation Models Slides

    36/147

    WHY INITWITHJSON ALONE IS NOT ENOUGH

    initWithJSON:

    View

    City

    CityViewController1. Controllerasks for Model

    3a. Model

    returns instance

    2. Controllcontinues

    3b. View di

    No guarantee that 3a happens before 3b

    USING NOTIFICATIONS TO DELAY EXECUTION

  • 7/30/2019 Operation Models Slides

    37/147

    initWithJSON:

    View

    City

    CityViewController1. Controllerasks for Model

    3. Model posts notificationwhen ready

    2. Con

    notifi

    5. Viedata

    NSNotificationCenter

    4. Consendswhenis hea

    NSNOTIFICATIONCENTER

  • 7/30/2019 Operation Models Slides

    38/147

    NSNotificationCenter

    postednotification

    subscribes

    notificationlistener

    notificationlistener

    notificationlistener

    notifies

    POSTING AND LISTENING FOR NOTIFICATIONS

  • 7/30/2019 Operation Models Slides

    39/147

    [[NSNotificationCenterdefaultCenter]

    addObserver:self selector:@selector(dataRetrieved

    name:@"initWithJSONFinishedL

    object:nil];

    [[NSNotificationCenterdefaultCenter]

    postNotificationName:@"initWithJSON object:nil];

    Sending a Notification

    Listening for a Notification

    ObserverInstance that is listening

    SelectorMethod to call whennotification is heard

    Name

    Unique notification nameObjectCan listen for notificationsfrom a specific object

    POSTING A NOTIFICATION IN INITWITHJSON

  • 7/30/2019 Operation Models Slides

    40/147

    J

    City.m ( inside initWithJSON )

    success:^(NSURLRequest *request, NSHTTPURLResponse *respon

    }

    self.name = JSON[@"name"]; self.state = JSON[@"state"];

    self.population = JSON[@"population"];

    AFJSONRequestOperation *operation = [AFJSONRequestOperation

    JSONRequestOperationWithRequest:request

    [[NSNotificationCenterdefaultCenter]

    postNotificationName:@"initWithJSONFinishedLoadin

    object:nil];

    Post a notification in the last line of the success block

    LISTENING FOR A NOTIFICATION IN A CONTRO

  • 7/30/2019 Operation Models Slides

    41/147

    CityViewController.m

    - (void)viewDidLoad {

    Florida

    238300

    - (void)dataRetrieved {

    NSLog(@"City state is: %@", self.city.state);

    NSLog(@"City population is: %@", self.city.population);

    }

    self.city = [[Cityalloc] initWithJSON];

    [[NSNotificationCenterdefaultCenter]

    addObserver:self

    selector:@selector(dataRetrieved)

    name:@"initWithJSONFinishedLoading"

    object:nil];

    MAKING INITWITHJSON THE DESIGNATED INIT

  • 7/30/2019 Operation Models Slides

    42/147

    J

    #import"City.h"

    @end

    City.m

    @implementation City

    AFJSONRequestOperation *operation = [AFJSONRequestOperation

    - (id)initWithJSON {

    self = [superinit];if(self) {

    }

    return self;}

    - (id)init {

    self = [selfinitWithJSON];return self;

    }

    CALLING INIT INSTEAD OF INITWITHJSON

  • 7/30/2019 Operation Models Slides

    43/147

    self.city = [[Cityalloc] init];

    [[NSNotificationCenterdefaultCenter]

    addObserver:self

    selector:@selector(dataRetrieved)

    name:@"initWithJSONFinishedLoading"

    object:nil];

    CityViewController.m

    - (void)viewDidLoad {

    }

    Notification n

    OHyeaaaaaaa

    Florid

    238300

    - (void)dataRetrieved {

    NSLog(@"City state is: %@", self.city.state);

    NSLog(@"City population is: %@", self.city.population);

    }

    INSTAPHOTOS USER.H BEFORE PHOTO REFACT

  • 7/30/2019 Operation Models Slides

    44/147

    User.h

    #import

    @interface User : NSObject

    @property (strong, nonatomic)NSString*firstName;

    @property (strong, nonatomic)NSString* ;profilePhoto@property (strong, nonatomic)NSString* ;profilePhotoThumbnail@property (strong, nonatomic)NSString*biography;@property (strong, nonatomic)NSString*memberSince;

    @end

    - (void)initWithJSON;

    @property (strong, nonatomic)NSString*lastName;

    @property (strong, nonatomic)NSString*location;

    INSTAPHOTOS USER.H AFTER PHOTO REFACTO

  • 7/30/2019 Operation Models Slides

    45/147

    User.h

    #import

    @end

    @interface User : NSObject

    @property (strong, nonatomic)Photo* ;profilePhoto

    #import"Photo.h"

    @property (strong, nonatomic)NSString*biography;@property (strong, nonatomic)NSString*memberSince;

    - (void)initWithJSON;

    CityViewCo

    User

    @property (strong, nonatomic)NSString*firstName;

    @property (strong, nonatomic)NSString*lastName;

    @property (strong, nonatomic)NSString*location;

    INSTAPHOTOS USER MODEL PROFILEPHOTO

  • 7/30/2019 Operation Models Slides

    46/147

    User.m

    AFJSONRequestOperation *operation = [AFJSONRequestOperation

    - (id)initWithJSON { self = [superinit];

    if(self) {

    This data should be in a Photo Model

    self.firstName = JSON[@"firstName"]; self.lastName = JSON[@"lastName"]; self.location = JSON[@"location"];

    self.biography = JSON[@"biography"]; self.memberSince = JSON[@"memberSince"];

    self.profilePhotoself.profilePhotoThumbnail

    ==JSON[@"profilePhoto"]JSON[@"profilePhotoThumb

    ;

    ...

    ...

  • 7/30/2019 Operation Models Slides

    47/147

    LEVEL 3

    PLANET HIG STRUCTURE SO FAR

  • 7/30/2019 Operation Models Slides

    48/147

    CityViewControllePlaceTableViewController InterestingPlacesTableViewController

    AppDelegate

    Lets see how this table view gets data

    EXAMINING PLACEDATA.JSON

  • 7/30/2019 Operation Models Slides

    49/147

    an NSArray co

    NSDictionary

    http://example.com/placeData.json

    [

    {

    "name": "Taco Cantina",

    "description": "Tasty tacos."

    },

    {

    "name": "Fish Town",

    "description": "Scrumptious sushi."

    },{

    "name": "Envy Labs",

    "description": "Enviable educators."

    }

    ]

    each NSDictio

    contains 2 NSS

    MAKING AN AFNETWORKING REQUEST FOR PLACEDA

    http://example.com/placeData.jsonhttp://example.com/placeData.json
  • 7/30/2019 Operation Models Slides

    50/147

    PlaceTableViewController.h

    @property (strong, nonatomic) NSArray *places;

    PlaceTableViewController.m

    NSURL *url = [[NSURL alloc] initWithString:@"http://example.com/place

    NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url];

    AFJSONRequestOperation *operation = [AFJSONRequestOperation

    JSONRequestOperationWithRequest:request

    success:^(NSURLRequest *request, NSHTTPURLResponse *response, id J

    self.places = JSON;} failure:^(NSURLRequest *request, NSHTTPURLResponse *response,

    NSError *error, id JSON) {

    NSLog(@"NSError: %@",error.localizedDescription);

    }];

    [operation start];

    This approach isnt creating Place

    MAKING PLACE OBJECTS

    http://codeschool.com/placeData.jsonhttp://codeschool.com/placeData.json
  • 7/30/2019 Operation Models Slides

    51/147

    PlaceTableViewController.h

    #import"Place.h"

    @property (strong, nonatomic) NSArray *places;

    PlaceTableViewController.mAFJSONRequestOperation *operation = [AFJSONRequestOperation

    JSONRequestOperationWithRequest:request

    success:^(NSURLRequest *request, NSHTTPURLResponse *response, id J

    }

    self.places = @[place1, place2, place3];

    Not efficient - what if there are 20 objects?

    Place*place1 = [[Placealloc]initWithName:JSON[0]["name"]

    description:JSON[0]["descripti

    Place*place2 = [[Placealloc]initWithName:JSON[1]["name"]

    description:JSON[1]["descripti

    Place*place3 = [[Placealloc]initWithName:JSON[2]["name"]

    description:JSON[2]["descripti

    USING FAST ENUMERATION

  • 7/30/2019 Operation Models Slides

    52/147

    0 1 2 3

    Fluffy Pepper Whiskers HiggieCat

    Console OutpNSArray *catNames> Cat name is

    > Cat name is

    > Cat name is

    > Cat name is

    a new Object that is local to theenumeration loop!

    The set/array you areenumerating through

    Now this is gospeed things ufor (NSString *catName in catNames) {

    NSLog(@"Cat name is: %@",catName);

    }

    CREATE NSARRAY OF MODEL OBJECTS WITH FAST ENUM

  • 7/30/2019 Operation Models Slides

    53/147

    for (NSDictionary *oneDictionary in JSON) {

    Place *newPlace = [[Placealloc] initWithName:oneDictionary[@" description:oneDictionary[@"

    }

    0 1 2

    Place object 1 Place object 2 Place object 3

    NSArray *places

    Our goal

    [self.placesaddObject:newPlace];

    Cant modify an NSArray

    LIST OF MUTABLE CLASSES

  • 7/30/2019 Operation Models Slides

    54/147

    Immutable Classes Mutable Classes

    NSString NSMutableString

    NSSet NSMutableSet

    NSArray NSMutableArray

    NSDictionary NSMutableDictionary

    NSData NSMutableData

    NSURLRequest NSMutableURLRequest

    Mutable Class objects can be modified after they are inst

    ADDING OBJECTS TO AN NSARRAY VIA A TEMPORARY NSMUTA

  • 7/30/2019 Operation Models Slides

    55/147

    for (NSDictionary *oneDictionary in JSON) {

    Place *newPlace = [[Placealloc] initWithName:oneDictionary[@" initWithDescription:oneDictionary[@"

    }

    0 1 2

    Place object 1 Place object 2 Place object 3

    NSArray *places

    NSMutableArray *tempArray = [[NSMutableArrayalloc] init];

    [tempArray addObject:newPlace];

    self.places = [[NSArrayalloc] initWithArray:tempArray];

    creating an immutable version with an existing mutable array

    We can add objects to mut

    PLACETABLEVIEWCONTROLLER UITABLEVIEW M

  • 7/30/2019 Operation Models Slides

    56/147

    Easy! Weve Done this

    a few times before

    PlaceTableViewController.m

    - (NSInteger)tableView:(UITableView *)tableView

    numberOfRowsInSection:(NSInteger)section {

    - (UITableViewCell *)tableView:(UITableView *)tableView

    cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    }

    - (void) tableView:(UITableView *)tableViewdidSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    }

    }

    UITABLEVIEW NUMBEROFROWSINSECTION: FROM PLACES @

  • 7/30/2019 Operation Models Slides

    57/147

    }

    PlaceTableViewController.m

    returnself.places.count;

    - (NSInteger)tableView:(UITableView *)tableView

    numberOfRowsInSection:(NSInteger)section {

    - (UITableViewCell *)tableView:(UITableView *)tableView

    cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    - (void) tableView:(UITableView *)tableViewdidSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    }

    }

    UITABLEVIEW CELLFORROWATINDEXPATH: FROM PLACES @

  • 7/30/2019 Operation Models Slides

    58/147

    PlaceTableViewController.m

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdenti

    if(cell == nil) {cell = [[UITableViewCellalloc] initWithStyle:UITableViewCel

    reuseIdentifier:@"pCell"];}

    return cell;

    Incorrect syntax

    - (UITableViewCell *)tableView:(UITableView *)tableView

    cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    }

    .name;cell.textLabel.text = self.places[indexPath.row]

    THE CORRECT WAY TO ACCESS MODEL OBJECT PRO

  • 7/30/2019 Operation Models Slides

    59/147

    PlaceTableViewController.m

    Correct syntax using message

    - (UITableViewCell *)tableView:(UITableView *)tableView

    cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdenti

    if(cell == nil) {cell = [[UITableViewCellalloc] initWithStyle:UITableViewCel

    reuseIdentifier:@"pCell"];}

    return cell;

    }

    ]name ;cell.textLabel.text = self.places[indexPath.row][

    PUSH A PLACE MODEL INSTANCE WHEN A CELL IS

  • 7/30/2019 Operation Models Slides

    60/147

    [tableView deselectRowAtIndexPath:indexPath animated:YES];

    }

    PlaceViewController *placeVC = [PlaceViewController alloc] init]

    placeVC.place = self.places[indexPath.row];

    [self.navigationControllerpushViewController:placeVC animated:Y

    PlaceTableViewController Cell PlaceV

    Place Model instance passed when cell is tapped

    - (void) tableView:(UITableView *)tableView

    didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    PlaceTableViewController.m

    PLACETABLEVIEWCONTROLLER

  • 7/30/2019 Operation Models Slides

    61/147

    DECLARING A PLACE @PROPERTY VARIABLE IN PLACEVIEWCO

  • 7/30/2019 Operation Models Slides

    62/147

    PlaceViewController.h

    @property (strong, nonatomic) Place *place;

    @interface PlaceViewController:UIViewController

    @property (strong, nonatomic) UILabel *placeNameLabel;

    #import"Place.h"

    PlaceViewController Place

    @property (strong, nonatomic) UILabel *placeDescriptionLabel;

    IMPLEMENTING SUBVIEWS IN PLACEVIEWCONTR

    Pl Vi C t ll

  • 7/30/2019 Operation Models Slides

    63/147

    PlaceViewController.m

    - (void)viewDidLoad {

    self.placeNameLabel = [[UILabelalloc] init];

    self.placeNameLabel.frame = CGRectMake(20,40,280,40);[self.viewaddSubview:self.placeNameLabel];

    self.placeDescriptionLabel = [[UILabelalloc] init];

    self.placeDescriptionLabel.frame = CGRectMake(20,100,280,20);

    [self.viewaddSubview:self.placeDescriptionLabel];

    }

    - (void)viewWillAppear:(BOOL)animated {

    self.placeNameLabel.text = self.place.name;

    self.placeDescriptionLabel.text=self.place.description;

    }

    create data containers in viewDidLoad

    set data in containers in viewWillAppear

    PUSHING TO PLACEVIEWCONTROLLER

  • 7/30/2019 Operation Models Slides

    64/147

    DECLARING @PROPERTY VARIABLES IN CITYVIEWCON

    CityViewController h

  • 7/30/2019 Operation Models Slides

    65/147

    CityViewController.h

    @property (strong, nonatomic) City *city;

    @interface CityViewController : UIViewController

    @property (strong, nonatomic) UILabel *cityNameLabel;

    #import"City.h"

    CityViewController City

    @property (strong, nonatomic) UILabel *cityStateLabel;

    @property (strong, nonatomic) UILabel *cityPopulationLabel;

    like

    did w

    IMPLEMENTING SUBVIEWS IN CITYVIEWCONT

  • 7/30/2019 Operation Models Slides

    66/147

    CityViewController.m

    - (void)viewDidLoad {

    self.cityNameLabel = [[UILabelalloc] init];

    self.cityNameLabel.frame = CGRectMake(20,40,280,40);

    [self.viewaddSubview:self.cityNameLabel];

    }

    - (void)viewWillAppear:(BOOL)animated {

    self.cityNameLabel.text = self.city.name;

    }

    Repeat for state and population data properties

    CITYVIEWCONTROLLER

  • 7/30/2019 Operation Models Slides

    67/147

    PLANET HIG STRUCTURE SO FAR

    A D l t

  • 7/30/2019 Operation Models Slides

    68/147

    CityViewPlaceTableViewController

    PlaceViewController

    InterestingPlacesTableViewController

    AppDelegate

  • 7/30/2019 Operation Models Slides

    69/147

    LEVEL 4

    ADDING THE ABILITY TO TAKE NOTES ABOUT A

  • 7/30/2019 Operation Models Slides

    70/147

    It really is a useful

    ADDING A NOTES @PROPERTY TO THE CITY MO

    Cit h

  • 7/30/2019 Operation Models Slides

    71/147

    #import

    @end

    City.h

    @interface City : NSObject

    @property (strong, nonatomic)NSString*name;

    - (id)initWithJSON;

    @property (strong, nonatomic)NSString*state;

    @property (strong, nonatomic)NSNumber*population;

    @property (strong, nonatomic)NSString*notes;

    INITIALIZING THE DEFAULT VALUE OF NOTES IN THE CI

    City m

  • 7/30/2019 Operation Models Slides

    72/147

    @end

    @implementation City

    - (id)init { self = [self initWithJSON];

    }

    - (id)initWithJSON { self = [selfinit];

    if(self) { ...

    self.notes = @"no notes yet";...

    }

    return self;}

    because the JSON file dohave any notes data

    City.m

    ADDING A UILABEL AND UITEXTFIELD FOR NOT

    CityViewController.h

  • 7/30/2019 Operation Models Slides

    73/147

    y

    @property (strong, nonatomic)UILabel*notesLabel;

    CityViewController.m

    - (void)viewDidLoad {

    self.notesLabel = [[UILabelalloc]init];

    self.notesLabel.frame = CGRectMake(20,160,280,40);

    }

    @property (strong, nonatomic)UITextField*notesField;

    @property (strong, nonatomic)City*city;

    self.notesField = [[UITextFieldalloc]init];

    self.notesField.frame = CGRectMake(15,220,290,30);

    self.notesLabel.text = self.city.notes;

    City *city=[[Cityalloc]init];

    EDITING TEXT IN PLANET HIG

  • 7/30/2019 Operation Models Slides

    74/147

    UITextField

    ACCESSING THE TEXT IN UITEXTFIELD

    Setting the text

  • 7/30/2019 Operation Models Slides

    75/147

    Setting the text

    self.notesField.text = @"Hi Jon!";

    Getting the text

    NSLog(@"%@",self.notesField.text);

    Just like a UILabel that

    you can edit!

    LIST OF KEYBOARDTYPE VALUES UIKeyboardT

  • 7/30/2019 Operation Models Slides

    76/147

    UIKeyboardTypeASCIICapable

    UIKeyboardTypeNumbersAndPunctuation

    UIKeyboardTypeURL

    UIKeyboardTypeNumberPad

    UIKeyboardTypePhonePad

    UIKeyboardTypeNamePhonePadUIKeyboardTypeEmailAddress

    UIKeyboardTypeDecimalPad

    UIKeyboardTypeTwitter

    UIKeyboardTypeAlphabet

    UIKeyboardT

    UIKeyboardT

    self.notesField.keyboardType = UIKeyboardTypeDefault;

    Other keyboard types

    LIST OF UITEXTFIELD BORDER STYLES

  • 7/30/2019 Operation Models Slides

    77/147

    self.notesField.borderStyle = UITextBorderStyleRoundedRect;

    Border StylesUITextBorderStyleNone

    UITextBorderStyleLine

    UITextBorderStyleBezel

    UITextBorderStyleRoundedRect

    MAKING THE KEYBOARD GO AWAY

  • 7/30/2019 Operation Models Slides

    78/147

    Dismissing the keyboard

    requires code from the

    UITextFieldDelegate Clas

    Tapping return shouldmake the keyboard goaway

    UITEXTFIELDDELEGATE METHODS

  • 7/30/2019 Operation Models Slides

    79/147

    - (BOOL)textFieldShouldBeginEditing:(UITextField *)textField;

    Runs when the Return key is tapped

    - (BOOL)textFieldDidBeginEditing:(UITextField *)textField;

    - (BOOL)textFieldShouldEndEditing:(UITextField *)textField;

    - (BOOL)textFieldDidEndEditing:(UITextField *)textField;

    - (BOOL) textField:(UITextField *)textFieldshouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string;

    - (BOOL)textFieldShouldClear:(UITextField *)textField;

    - (BOOL)textFieldShouldReturn:(UITextField *)textField;

    GETTING TEXTFIELDSHOULDRETURN: IN CITYVIEWCON

    UITextFieldDelegate

  • 7/30/2019 Operation Models Slides

    80/147

    CityViewController

    Protocols are a way to get

    methods from one Class

    into another

    UITextFieldDelegate

    SETTING UP THE UITEXTFIELDDELEGATE PROTO

    CityViewController.h

  • 7/30/2019 Operation Models Slides

    81/147

    y

    @interface CityViewController:UIViewController

  • 7/30/2019 Operation Models Slides

    82/147

    - (BOOL)textFieldShouldReturn:(UITextField *)textField{

    }

    // 1. Update the City Model object with the text in notesFiel

    // 2. Make the keyboard go away

    CityViewController.m

    self.city.notes = self.notesField.text;

    [textField resignFirstResponder];

    returnYES;

    WHICH VIEW IS THE FIRST RESPONDER?

    ViCit Vi C t ll

  • 7/30/2019 Operation Models Slides

    83/147

    notesField is the F

    Responder when t

    keyboard is onscre

    ViewCityViewController

    notesLabel notesField

    WHICH VIEW IS THE FIRST RESPONDER?

    ViewCityViewController

  • 7/30/2019 Operation Models Slides

    84/147

    notesField is no lo

    First Responder w

    keyboard is dismis

    ViewCityViewController

    notesLabel notesField

    PROBLEM: THE UITEXTFIELD IS IN CITYVIEWCONT

  • 7/30/2019 Operation Models Slides

    85/147

    ViewCityViewController

    notesLabel notesField

    SOLUTION: MOVE THE UITEXTFIELD TO ANOTHER CON

  • 7/30/2019 Operation Models Slides

    86/147

    EditNoteViewController CityViewController View

    notesLabel

    ADD A UIBUTTON TO SWITCH TO EDITNOTEVIEWCON

    CityViewController.m

  • 7/30/2019 Operation Models Slides

    87/147

    - (void)viewDidLoad {

    }

    UIButton *editButton = [UIButtonbuttonWithType:UIButtonTypeRound

    editButton.frame = CGRectMake(20,220,280,50);

    [editButton setTitle:@"Edit Note"forState:UIControlStateNormal]

    [self.viewaddSubview:editButton];

    [editButton addTarget:self

    forControlEvents:UIControlEventTouchUpInside];

    action:@selector(editPressed)

    }

    - (void)editPressed {

    EditNoteViewController *editNoteVC = [[EditNoteViewControllerall

    [self.navigationControllerpushViewController:editNoteVC animated

    editNoteVC.city = self.city;

    DECLARING @PROPERTY VARIABLES IN EDITNOTEVIEWCO

    EditNoteViewController.h

  • 7/30/2019 Operation Models Slides

    88/147

    @interface EditNoteViewController:UIViewController

  • 7/30/2019 Operation Models Slides

    89/147

    - (void)viewWillAppear:(BOOL)animated {

    }

    self.notesField.delegate = self;

    self.notesField.text = self.city.notes;

    - (void)viewDidLoad {

    }

    self.notesField = [[UITextFieldalloc]init];

    self.notesField.frame = CGRectMake(15,50,290,30);

    self.city=[[Cityalloc]init];

    CREATE A UIBUTTON TO GET BACK TO CITYVIEWCON

    EditNoteViewController.m

  • 7/30/2019 Operation Models Slides

    90/147

    - (void)viewDidLoad {

    }

    UIButton *saveButton = [UIButtonbuttonWithType:UIButtonTypeRoun

    saveButton.frame = CGRectMake(15,100,290,50);

    [saveButton setTitle:@"Save Note"forState:UIControlStateNormal]

    [self.viewaddSubview:saveButton];

    [saveButton addTarget:selfaction:@selector(savePressed)

    forControlEvents:UIControlEventTouch

    }

    - (void)savePressed {

    [self.navigationControllerpopViewControllerAnimated:YES];

    self.city.notes = self.notesField.text;

    EDITNOTEVIEWCONTROLLER DE

  • 7/30/2019 Operation Models Slides

    91/147

    PUSHING EDITNOTEVC ONTO THE NAVIGATION S

    CityViewController.m

  • 7/30/2019 Operation Models Slides

    92/147

    }

    - (void)editPressed {

    EditNoteViewController *editNoteVC = [[EditNoteViewControlleral

    [self.navigationControllerpushViewController:editNoteVC animated

    editNoteVC.city = self.city;

    Only Use a Navigationcontroller stack if

    need to move through a hierarchy of view

    OPENING EDITNOTEVC AS A MODAL VIEW

    CityViewController.m

  • 7/30/2019 Operation Models Slides

    93/147

    [selfpresentViewController:editNoteVCanimated:YEScompletion:n

    - (void)editPressed {

    EditNoteViewController *editNoteVC = [[EditNoteViewControlleral

    editNoteVC.city = self.city;

    }

    MAKING A MODAL VIEW GO AWAY

    EditNoteViewController.m

  • 7/30/2019 Operation Models Slides

    94/147

    }

    - (void)savePressed {

    [selfdismissViewControllerAnimated:YES completion:nil];

    self.city.notes = self.notesField.text;

    USING A UIBARBUTTONITEM INSTEAD OF A UI

    CityViewController.m

  • 7/30/2019 Operation Models Slides

    95/147

    }

    returnself;

    } Check the Apple docs for all of the UIBarButtonSyste

    - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)ni

    self = [superinitWithNibName:nibNameOrNil bundle:nibBundleOrNil

    if(self) {

    self.title = @"City"; self.tabBarItem.image = [UIImageimageNamed:@"tab_icon_city"

    self.navigationItem.rightBarButtonItem = editButton;

    UIBarButtonItem *editButton = [[UIBarButtonItemalloc]

    initWithBarButtonSystemItem:UIBarButtonSystemI

    target:self

    action:@selector(editPres

    OPENING EDITNOTEVIEWCONT

    WITH AS A MODAL VIEW

  • 7/30/2019 Operation Models Slides

    96/147

    PLANET HIG STRUCTURE SO FARAppDelegate

  • 7/30/2019 Operation Models Slides

    97/147

    CityViewContr

    EditNoteView

    PlaceTableViewController

    PlaceViewController

    InterestingPlacesTableViewController

  • 7/30/2019 Operation Models Slides

    98/147

    LEVEL 5

    WHAT HAPPENS WHEN PLANECLOSED?

  • 7/30/2019 Operation Models Slides

    99/147

    AWW COME ON - It TOOK

    FOREVER TO MAKE THAT

    SAVING MODEL DATA USING THE NSCODING PR

  • 7/30/2019 Operation Models Slides

    100/147

    NSCoding all

    easily store a

    retrieve our NSString NSArray

    Packaged Model Data

    NSDictionary NSNumber

    NSCoding

    File

    NSCODING IS LIKE A PACKING BOX

    NSKeyedArchiver/Unarchiver

  • 7/30/2019 Operation Models Slides

    101/147

    NSCoding

    NSCoding is thepacking box that

    contains your data

    NSKeyedArchiver

    +

    Unarchiver

    F

    (

    is the delivery person

    The

    the

    City

    City.h

    @interface City : NSObject

    ADOPTING THE NSCODING PROTOCOL

  • 7/30/2019 Operation Models Slides

    102/147

    #import"City.h"

    @end

    City.m

    - (id)init ...

    @interface City:NSObject

    - (id)initWithJSON ...

    - (City*)initWithCoder:(NSCoder *)aDecoder {

    }

    - (void)encodeWithCoder:(NSCoder *)anEncoder {

    }

    initWithCoder

    returnan instModel

    must now impleinitWithCoder

    encodeWithCod

    IMPLEMENTING ENCODEWITHCODER:

    City m

    encodeWithCoder:formats data so it can be arc

  • 7/30/2019 Operation Models Slides

    103/147

    City.m

    Use @property namesas key names

    @"name"@"state"

    @"population"

    @"notes"];

    ]

    ];];

    Model properties

    [anEncoder encodeObject:[anEncoder encodeObject:

    [anEncoder encodeObject:

    [anEncoder encodeObject:

    self.nameself.state

    self.population

    self.notes

    forKey:forKey:

    forKey:

    forKey:

    - (void)encodeWithCoder:(NSCoder *)anEncoder {

    }

    IMPLEMENTING INITWITHCODER:

    City.m

    initWithCoder:unpacks data into a new object

  • 7/30/2019 Operation Models Slides

    104/147

    y

    - (City*)initWithCoder:(NSCoder *)aDecoder {

    self = [super init];if(self) {

    }

    return self;

    }

    @"name"

    @"state"

    @"populati

    @"notes"];

    ];

    ];

    Use @property naas key names

    Model properties

    = [aDecoderdecodeObjectForKey:

    = [aDecoder decodeObjectForKey:

    = [aDecoder decodeObjectForKey:

    = [aDecoder decodeObjectForKey:

    self.name

    self.state

    self.population

    self.notes

    USE THE NSKEYED METHODS TO WORK WITH NinitWithCoder:andencodeWithCoder:dont get ca

  • 7/30/2019 Operation Models Slides

    105/147

    Unarchive a Model with initWithCoder

    City *city = [NSKeyedUnarchiverunarchiveObjectWithFile:ARCHIVE_P

    Archive a Model with encodeWithCoder

    City *city = [[Cityalloc] initWithJSON];

    [NSKeyedArchiverarchiveRootObject:city toFile:ARCHIVE_PATH];

    both need a patharchive file (war

    IOS APP FOLDER HIERARCHY

    d

  • 7/30/2019 Operation Models Slides

    106/147

    APP App.bundle

    DocumentsLibrary

    tmp

    Caches

    Preferences

    good place to saveModel data

    read-only

    PROGRAMMATICALLY ACCESSING THE DOCUMENTS

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDir

  • 7/30/2019 Operation Models Slides

    107/147

    Give your archives a meaningful na

    Unarchive a Model

    Archive a Model

    City *city = [[Cityalloc] initWithJSON];

    archivePath];

    archivePat

    [docsDir stringByAppendingPathComponent:@"NSString *archivePath =

    [NSKeyedArchiverarchiveRootObject:city toFile:

    City *city = [NSKeyedUnarchiverunarchiveObjectWithFile:

    NSUserDomainMY

    NSString *docsDir = [paths objectAtIndex:0];

    CREATING A CLASS METHOD TO FIND THE ARCHI

    + (NSString *)getPathToArchive {

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumen

    Dont forget to also declare this meClass method

  • 7/30/2019 Operation Models Slides

    108/147

    Unarchive a Model

    Archive a Model

    [CitygetP

    [CitygetPathToArch

    City *city = [NSKeyedUnarchiverunarchiveObjectWithFile:

    City *city = [[Cityalloc] initWithJSON];

    [NSKeyedArchiverarchiveRootObject:city toFile:

    }

    [docsDir stringByAppendingPathComponent:@"city.model"];return

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumenNSUserDom

    NSString *docsDir = [paths objectAtIndex:0];

    CLASS METHODS TO SAVE AND RETRIEVE A MO

    + (NSString *)getPathToArchive {

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumen

  • 7/30/2019 Operation Models Slides

    109/147

    Just call these methods to save/retrieve the archive

    + (void)saveCity(City *)aCity {

    }

    + (City *)getCity {

    }

    [NSKeyedArchiverarchiveRootObject:aCity toFile:

    return [NSKeyedUnarchiverunarchiveObjectWithFile:

    }

    [docsDir stringByAppendingPathComponent:@"city.model"];return

    City.m Class methods

    [CitygetPat

    [CitygetPathT

    NSString *docsDir = [paths objectAtIndex:0];

    NSUserDomNSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumen

    WHERE AND WHEN TO ARCHIVE A MODEL OBJAppDelegate During Instantiatio

  • 7/30/2019 Operation Models Slides

    110/147

    CityViewContr

    EditNoteView

    PlaceTableViewController

    PlaceViewController

    InterestingPlacesTableViewController

    WHERE AND WHEN TO ARCHIVE A MODEL OBJ

    City.mDuring Instantiatio

  • 7/30/2019 Operation Models Slides

    111/147

    - (id)initWithJSON {

    self = [superinit];

    if(self) {

    ... // AFNetworking success block

    self.name = JSON[@"name"];

    self.state = JSON[@"state"];

    self.population = JSON[@"population"];

    [CitysaveCity:self];

    }

    returnself;

    }

    WHERE AND WHEN TO ARCHIVE A MODEL OBJAppDelegate After editing

  • 7/30/2019 Operation Models Slides

    112/147

    CityViewContr

    EditNoteView

    PlaceTableViewController

    PlaceViewController

    InterestingPlacesTableViewController

    textFieldShouldReturn:or savePressed:

    WHERE AND WHEN TO ARCHIVE A MODEL OBJ

    EditNoteViewController.m

    After editing

  • 7/30/2019 Operation Models Slides

    113/147

    - (BOOL)textFieldShouldReturn:(UITextField *)textField;

    }

    returnYES;

    self.city.notes = self.notesField.text;

    [textFieldresignFirstResponder];

    [CitysaveCity:self.city];

    WHERE AND WHEN TO ARCHIVE A MODEL OBJ

    When the app close

  • 7/30/2019 Operation Models Slides

    114/147

    Wait, code runs even when

    the app Closes?

    UIAPPLICATIONDELEGATE PROTOCOL METHODAppDelegate.h

    @interface AppDelegate : UIResponder

  • 7/30/2019 Operation Models Slides

    115/147

    @interface AppDelegate:UIResponder

    - (BOOL)application:(UIApplication *)applicationwillFinishLaunchingWithOptions:(NSDictionary *)options

    - (BOOL)application:(UIApplication *)application

    didFinishLaunchingWithOptions:(NSDictionary *)options

    - (void)applicationDidBecomeActive:(UIApplication *)application- (void)applicationWillResignActive:(UIApplication *)application

    - (void)applicationDidEnterBackground:(UIApplication *)application

    - (void)applicationWillEnterForeground:(UIApplication *)applicatio

    APPLICATION LIFECYCLEapplication:willFinishLaunchingWithOpUser taps app

    icon for the

  • 7/30/2019 Operation Models Slides

    116/147

    applicationDidBecomeActive:

    application:didFinishLaunchingWithOpt

    applicationWillResignActive:

    applicationDidEnterBackground:

    applicationWillEnterForeground:

    first time

    app visuals appear

    app interrupted- call comes in- home button tapped

    normal usage

    PERFORMING OPERATIONS IN THE APPDELEGAAppDelegate.m

    @implementation AppDelegate

  • 7/30/2019 Operation Models Slides

    117/147

    @ p e e a o pp e ega e

    - (void)applicationDidEnterBackground:(UIApplication *)applicatio

    - (void)applicationWillEnterForeground:(UIApplication *)applicati

    }

    }

    // archive Model

    // unarchive Model

    Problem: The City Model object is in

    CityViewController, not AppDelegate

    APP DELEGATE NOTIFICATIONS

    UIApplicationDidEnterBackgroundNAppDelegate

  • 7/30/2019 Operation Models Slides

    118/147

    CityViewContr

    EditNoteView

    PlaceTableViewController

    PlaceViewController

    InterestingPlacesTableViewController

    LISTENING FOR THE APPLICATION CLOSINGCityViewController.m

    - (void)viewDidLoad {

  • 7/30/2019 Operation Models Slides

    119/147

    [[NSNotificationCenterdefaultCenter]

    addObserver:self

    selector:@selector(entering

    - (void)entering

    Dont forget to re-creat

    Model when the app open

    Backgroundname:UIApplicationDidEnterBackgroundNotification

    object:nil];

    }

    )

    Background {

    [CitysaveCity:self.city];

    }

    LISTENING FOR THE APPLICATION OPENINGCityViewController.m

    - (void)viewDidLoad {

  • 7/30/2019 Operation Models Slides

    120/147

    [[NSNotificationCenterdefaultCenter]

    addObserver:self

    selector:@selector(entering

    - (void)entering

    Foreground)name:UIApplicationWillEnterForegroundNotification

    object:nil];

    }

    Foreground {

    self.city = [City getCity];

    }

    WHERE AND WHEN TO UNARCHIVE A MODEL O

    In Views that might need a Mo

    but dont get a copy of it passe

  • 7/30/2019 Operation Models Slides

    121/147

    PlaceTableViewController

    PlaceViewController

    CityViewContro

    EditNoteViewCo

    The City model isnt passed,so get it from the archive

    CitPlace

    WHERE AND WHEN TO UNARCHIVE A MODEL OPlaceTableViewController.h

    #import"City.h"

  • 7/30/2019 Operation Models Slides

    122/147

    @property (strong, nonatomic)City *city;

    PlaceTableViewController.m

    - (void)viewWillAppear:(BOOL)animated {

    self.city = [City getCity];

    }

    PLANET HIG SAVING DATA

  • 7/30/2019 Operation Models Slides

    123/147

  • 7/30/2019 Operation Models Slides

    124/147

    LEVEL 6

    PLANET HIG - INTERESTINGPLACESTABLEVIEWCON

    AppDelegate

  • 7/30/2019 Operation Models Slides

    125/147

    CityViewContr

    EditNoteView

    PlaceTableViewController

    PlaceViewController

    InterestingPlacesTableViewController

    Lets get this tableview working

    ADDING AN INTERESTINGPLACES NSARRAY @PR

    #import

    City.h

  • 7/30/2019 Operation Models Slides

    126/147

    @end

    @interface City : NSObject

    @property (strong, nonatomic)NSString*name;

    - (id)initWithJSON;

    @property (strong, nonatomic)NSString*state;

    @property (strong, nonatomic)NSNumber*population;

    @property (strong, nonatomic)NSString*notes;

    @property (strong, nonatomic)NSArray* ;interestingPlaces

    SETTING THE INITIAL VALUE OF INTERESTINGP

    City.m

    @implementation City No default interesting plac

  • 7/30/2019 Operation Models Slides

    127/147

    @end

    - (id)init { self = [self initWithJSON];

    }

    - (id)initWithJSON { self = [selfinit];

    if(self) { ...

    ...}

    return self;}

    = nil;self.interestingPlaces

    GETTING THE CITY MODEL INTO PLACEVIEWCON

    PlaceViewController.h

    #import

  • 7/30/2019 Operation Models Slides

    128/147

    @property (strong, nonatomic) City *city;

    #import

    #import"City.h"

    @end

    @interface PlaceViewController : UIViewController

    @property (strong, nonatomic) Place *place;

    #import"Place.h"

    -(void) (id)sender;makeThisPlaceInteresting:

    ADDING A UIBUTTON TO MARK A PLACE AS INTE

    PlaceViewController.m

    -(void)viewWillAppear:(BOOL)animated{

  • 7/30/2019 Operation Models Slides

    129/147

    ...

    }

    UIButton *interestingButton = [UIButtonbuttonWithType:UIButtonTyp

    interestingButton.frame = CGRectMake(60,100,200,44);

    [interestingButton setTitle:@"Mark as Interesting"forState:UICont

    [self.viewaddSubview:interestingButton];

    [interestingButton addTarget:self

    forControlEvents:UIControlEventTouchUpInside];

    action:@selector( )makeThisPlaceInteresting:

    self.city = [CitygetCity];

    IMPLEMENTING MAKETHISPLACEINTERESTING

    NSMutableArray *tempArray = [[NSMutableArray alloc]

    -(void) (id)sender{

    PlaceViewController.m

    makeThisPlaceInteresting:

  • 7/30/2019 Operation Models Slides

    130/147

    }

    [CitysaveCity:self.city];

    NSMutableArray *tempArray = [[NSMutableArrayalloc]

    initWithArray:self.city.interest

    [tempArray addObject:self.place];

    self.city.interestingPlaces = [[NSArrayalloc] initWithArray:tem

    PLACEVIEWCONTROLLER DEM

  • 7/30/2019 Operation Models Slides

    131/147

    INTERESTINGPLACESTABLEVIEWCONTROLLER UITABLEVIEW

    InterestingPlacesTableViewController.m

    - (NSInteger)tableView:(UITableView *)tableView

    numberOfRowsInSection:(NSInteger)section {

  • 7/30/2019 Operation Models Slides

    132/147

    returnself.city.interestingPlaces.count;

    }

    - (UITableViewCell *)tableView:(UITableView *)tableView

    cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    }

    - (void) tableView:(UITableView *)tableView

    didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    }

    UITABLEVIEW CELLFORROWATINDEXPATH: FROM

    InterestingPlacesTableViewController.m

    - (UITableViewCell *)tableView:(UITableView *)tableView

    cellForRowAtIndexPath:(NSIndexPath *)indexPath {

  • 7/30/2019 Operation Models Slides

    133/147

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdenti

    if(cell == nil) {cell = [[UITableViewCellalloc] initWithStyle:UITableViewCel

    reuseIdentifier:@"pCell"];}

    cell.textLabel.text = [self.city.interestingPlaces[indexPath.row

    return cell;

    }

    PUSH A PLACE MODEL INSTANCE WHEN A CELL IS

    InterestingPlacesTableViewController.m

    - (void) tableView:(UITableView *)tableView

    didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

  • 7/30/2019 Operation Models Slides

    134/147

    [tableView deselectRowAtIndexPath:indexPath animated:YES];

    }

    PlaceViewController *placeVC = [PlaceViewController alloc] init]

    placeVC.place = self.city.interestingPlaces[indexPath.row];

    [self.navigationControllerpushViewController:placeVC animated:Y

    InterestingPlacesTableViewController Cell PlaceVPlace Model instance passed when cell is tapped

    INTERESTINGPLACES

    TABLEVIEWCONTROLLER DEMO

  • 7/30/2019 Operation Models Slides

    135/147

    REMOVE THE BUTTON AFTER ADDING A PLACE

    PlaceViewController.m

    - (void)makeThisPlaceInteresting:(id)sender{

    sender is the button that called the

  • 7/30/2019 Operation Models Slides

    136/147

    }

    self.city = [CitygetCity];

    NSMutableArray *tempArray = [[NSMutableArrayalloc]initWithArray:self.city.intere

    [tempArray addObject:[[Placealloc] initWithName:self.placeName

    description:self.placeDesc

    self.city.interestingPlaces = [[NSArrayalloc] initWithArray:te

    [CitysaveCity:self.city];

    [sender removeFromSuperview];

    SHOW AN ALERT VIEW WHEN MAKING A PLACE INT

    PlaceViewController.m

    - (void)makeThisPlaceInteresting:(id)sender{

  • 7/30/2019 Operation Models Slides

    137/147

    }

    [sender removeFromSuperview];

    ...

    UIAlertView *alert = [[UIAlertViewalloc] initWithTitle:@"Place favorited"

    message:@"This Place is now in your fav

    delegate:nil

    cancelButtonTitle:@"OK"

    otherButtonTitles:nil];

    [alert show];

    UIALERTVIEW ELEMENTS

    UIAlertView *alert = [[UIAlertViewalloc]

    initWithTitle:@"Place favorited"

    message:@"This Place is now in your favorites

  • 7/30/2019 Operation Models Slides

    138/147

    title messag

    cancelButtonTitle

    delegate:nil

    cancelButtonTitle:@"OK"

    otherButtonTitles:nil];

    PROBLEM: THE BUTTON COM

  • 7/30/2019 Operation Models Slides

    139/147

    DONT SHOW THE BUTTON IF THE PLACE IS ALREADY INT

    PlaceViewController.m

    -(void)viewWillAppear:(BOOL)animated{

    if(![self.city.interestingPlacescontainsObject:self.place]) {

  • 7/30/2019 Operation Models Slides

    140/147

    }

    // show the button because this Place isn't interesting ye

    } else { // don't show the button because this Place is already int

    }

    Thats a bummer, man!

    DONT SHOW THE BUTTON IF THE PLACE IS ALREADY INT

    PlaceViewController.m

    BOOLplaceAlreadyInteresting = NO;

    -(void)viewWillAppear:(BOOL)animated{

  • 7/30/2019 Operation Models Slides

    141/147

    for (Place *p in self.city.interestingPlaces) {

    }

    if([p.nameisEqualToString:self.place.name]) {placeAlreadyInteresting = YES;

    }

    }

    // show the button because this Place isn't interesting ye

    } else {

    // don't show the button because this Place is already int

    }

    if( ) {!placeAlreadyInteresting

    ACCESSING UITABBARITEMS

    tabBarController.tabBa

  • 7/30/2019 Operation Models Slides

    142/147

    badgeitems[0] items[1]

    self.tabBarController.tabBar.ite

    the Interesting Places tabBarItem

    SET THE UITABBARITEM BADGE VALUE

    UITabBarItem Property

  • 7/30/2019 Operation Models Slides

    143/147

    Convert the count integer to an NSString

    [self.tabBarController.tabBar.items[1]

    setBadgeValue:[NSStringstringWithFormat:@

    self.city.interestingPlaces

    WHERE AND WHEN TO UPDATE SETBADGEVAL

    AppDelegateUpdate when the app firs

  • 7/30/2019 Operation Models Slides

    144/147

    CityViewContr

    EditNoteView

    PlaceTableViewController

    PlaceViewController

    InterestingPlacesTableViewController

    Update inmakeThisPlaceInteresting:

    UPDATE THE BADGE WHEN THE APP LAUNCHES

    AppDelegate.h

    @interface AppDelegate:UIResponder

    #import"City.h"

  • 7/30/2019 Operation Models Slides

    145/147

    AppDelegate.m

    - (BOOL) application:(UIApplication *)applicationdidFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    }

    ...

    City *city = [CitygetCity];

    [tabBarController.tabBar.items[1]

    setBadgeValue:[NSStringstringWithFormat:@city.interestingPlaces.coun

    if(city) {

    }

    UPDATE THE BADGE WHEN A PLACE IS MARKED INTERES

    PlaceViewController.m

    - (void)makeThisPlaceInteresting:(id)sender{

    ...UIAlertView *alert = [[UIAlertViewalloc]

  • 7/30/2019 Operation Models Slides

    146/147

    }

    [sender removeFromSuperview];

    initWithTitle:@"Place favorited"

    message:@"This Place is now in your favor

    delegate:nil

    cancelButtonTitle:@"OK"

    otherButtonTitles:nil];

    [alert show];

    [self.tabBarController.tabBar.items[1]

    setBadgeValue:[NSStringstringWithFormself.city.interestingPl

    PLANET HIG

  • 7/30/2019 Operation Models Slides

    147/147

    This thing just keeps

    getting better!