• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
iOS app case study
 

iOS app case study

on

  • 3,233 views

The slides from a lecture I gave at RMIT doing a case study of a simple property search application.

The slides from a lecture I gave at RMIT doing a case study of a simple property search application.

Statistics

Views

Total Views
3,233
Views on SlideShare
2,176
Embed Views
1,057

Actions

Likes
10
Downloads
64
Comments
0

5 Embeds 1,057

http://www.stewgleadow.com 864
http://sgleadow.github.com 149
http://localhost:4000 25
http://localhost 18
http://translate.googleusercontent.com 1

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    iOS app case study iOS app case study Presentation Transcript

    • iPhone App Case Study Stewart Gleadow sgleadow@thoughtworks.com @stewgleadowFriday, 16 September 11
    • Why iPhone development?Friday, 16 September 11
    • YOW Conference • Workshops November 28-30 • Conference December 1-2 • http://www.yowconference.com.au/ • lisa@yowconference.comFriday, 16 September 11
    • Common features in iPhone appsFriday, 16 September 11
    • Outline 1. Basic table views 2. Custom table views 3. Dynamic content 4. Master/detail navigation 5. Make it awesomeFriday, 16 September 11
    • GamesFriday, 16 September 11
    • Camera controlFriday, 16 September 11
    • Basic tablesFriday, 16 September 11
    • Advanced tablesFriday, 16 September 11
    • FormsFriday, 16 September 11
    • Scroll viewsFriday, 16 September 11
    • MapsFriday, 16 September 11
    • Location awarenessFriday, 16 September 11
    • Master/detail navigationFriday, 16 September 11
    • Master/detail navigationFriday, 16 September 11
    • Consuming and presenting information from the webFriday, 16 September 11
    • Build up your toolboxFriday, 16 September 11
    • Build up your toolbox http://cocoawithlove.com/2011/06/process-of-writing-ios-application.htmlFriday, 16 September 11
    • Build up your toolbox http://cocoawithlove.com/2011/06/process-of-writing-ios-application.htmlFriday, 16 September 11
    • 1. Basic table viewFriday, 16 September 11
    • Property An Objective C domain model classFriday, 16 September 11
    • Property An Objective C domain model class @interface Property : NSObject @property (nonatomic, copy) NSString *address; @property (nonatomic, copy) NSString *suburb; @property (nonatomic, copy) NSString *postode; @property (nonatomic, retain) UIImage *photo; @property (nonatomic, copy) NSString *summary; - (NSString *)location; @endFriday, 16 September 11
    • Property An Objective C domain model class @interface Property : NSObject @property (nonatomic, copy) NSString *address; @property (nonatomic, copy) NSString *suburb; @property (nonatomic, copy) NSString *postode; @property (nonatomic, retain) UIImage *photo; @property (nonatomic, copy) NSString *summary; - (NSString *)location; @end Put logic in your model classesFriday, 16 September 11
    • Property Make your objects easy to create and configureFriday, 16 September 11
    • Property Make your objects easy to create and configure + (Property *)propertyWithAddess:(NSString *)anAddress suburb:(NSString *)aSuburb postcode:(NSString *)aPostcode photo:(NSString *)photoName summary:(NSString *)aSummary; { Property *property = [[[Property alloc] init] autorelease]; property.address = anAddress; property.suburb = aSuburb; property.postode = aPostcode; property.photo = [UIImage imageNamed:photoName]; property.summary = aSummary; return property; }Friday, 16 September 11
    • UIViewController UITableViewFriday, 16 September 11
    • UIViewController UITableView UITableViewDataSource UITableViewDelegate UITableViewCellFriday, 16 September 11
    • UITableViewFriday, 16 September 11
    • UITableView Creating your UITableView UITableView *table; table = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];Friday, 16 September 11
    • UITableView Creating your UITableView UITableView *table; table = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain]; Setting up your delegates table.delegate = self; table.dataSource = self;Friday, 16 September 11
    • UITableView Creating your UITableView UITableView *table; table = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain]; Setting up your delegates table.delegate = self; table.dataSource = self; Adding the table to the view [self.view addSubview:table];Friday, 16 September 11
    • UITableViewFriday, 16 September 11
    • UITableViewFriday, 16 September 11
    • UITableViewCellFriday, 16 September 11
    • UITableViewCell Creating a table cell - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier;Friday, 16 September 11
    • UITableViewCell Creating a table cell - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier; [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"RMITCellIdentifier"];Friday, 16 September 11
    • UITableViewCell Creating a table cell - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier; [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"RMITCellIdentifier"]; Reuse is importantFriday, 16 September 11
    • UITableViewCell Creating a table cell - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier; [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"RMITCellIdentifier"]; Reuse is important Configuring the cell cell.textLabel.text = @"title string"; cell.detailTextLabel.text = @"subtitle string";Friday, 16 September 11
    • UITableViewDataSourceFriday, 16 September 11
    • UITableViewDataSource How many sections do I have?Friday, 16 September 11
    • UITableViewDataSource How many sections do I have? - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView;Friday, 16 September 11
    • UITableViewDataSource How many sections do I have? - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView; How many rows are in each section?Friday, 16 September 11
    • UITableViewDataSource How many sections do I have? - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView; How many rows are in each section? - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;Friday, 16 September 11
    • UITableViewDataSource How many sections do I have? - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView; How many rows are in each section? - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section; What is the cell for a given row/section?Friday, 16 September 11
    • UITableViewDataSource How many sections do I have? - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView; How many rows are in each section? - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section; What is the cell for a given row/section? - (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;Friday, 16 September 11
    • Demo 1: Basic table viewFriday, 16 September 11
    • 2. Custom table viewFriday, 16 September 11
    • UITableViewCell textLabel imageView detailTextLabelFriday, 16 September 11
    • UITableViewCell textLabel imageView detailTextLabel Plus: • backgroundView • selectedBackgroundView • contentViewFriday, 16 September 11
    • Customising Cells if (cell == nil) { cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier] autorelease]; self.textLabel.backgroundColor = [UIColor clearColor]; self.textLabel.font = [UIFont boldSystemFontOfSize:14]; self.textLabel.shadowOffset = CGSizeMake(0, 1); // And a whole lot more }Friday, 16 September 11
    • Customising Cells if (cell == nil) { cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier] autorelease]; self.textLabel.backgroundColor = [UIColor clearColor]; self.textLabel.font = [UIFont boldSystemFontOfSize:14]; self.textLabel.shadowOffset = CGSizeMake(0, 1); // And a whole lot more }Friday, 16 September 11
    • Customising Cells if (cell == nil) { cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier] autorelease]; self.textLabel.backgroundColor = [UIColor clearColor]; self.textLabel.font = [UIFont boldSystemFontOfSize:14]; self.textLabel.shadowOffset = CGSizeMake(0, 1); // And a whole lot more } Refactor into our own styled cell classFriday, 16 September 11
    • PropertyCell A subclass of UITableViewcellFriday, 16 September 11
    • PropertyCell A subclass of UITableViewcell - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { if ((self = [super initWithStyle:style reuseIdentifier:reuseIdentifier])) { self.textLabel.textColor = [UIColor darkGrayColor]; self.textLabel.backgroundColor = [UIColor clearColor]; // More cell styling code goes here } return self; }Friday, 16 September 11
    • Demo 2: Custom table viewFriday, 16 September 11
    • 3. Dynamic contentFriday, 16 September 11
    • Backend server • Hosted on Heroku • http://rmit-property-search.heroku.com/search • Written in Ruby • Uses the Sinatra frameworkFriday, 16 September 11
    • Server codeFriday, 16 September 11
    • Server code require rubygems require bundler require erb Bundler.require get /search do @search = params[:q] erb :properties endFriday, 16 September 11
    • Server code require rubygems require bundler require erb Bundler.require get /search do @search = params[:q] template erb :properties end JSON fileFriday, 16 September 11
    • Example JSONFriday, 16 September 11
    • Example JSON { "title" : "", "properties" : [ { "address" : "60-74 Buckingham Drive", "suburb" : "Heidelberg", "postcode" : "3084", "photo" : "photo1.jpg", "summary" : "Banyule House, 1839" }, { "address" : "3 Macedon Street", "suburb" : "Sunbury", "postcode" : "3429" , "photo" : "photo10.jpg", "summary" : "Rupertswood" }, ... ] }Friday, 16 September 11
    • NetworkingFriday, 16 September 11
    • Networking Don’t reinvent the wheelFriday, 16 September 11
    • Networking Don’t reinvent the wheel • NSURLConnection • ASIHttpRequest • LRResty • AFNetworking • RestKitFriday, 16 September 11
    • Networking Don’t reinvent the wheel • NSURLConnection • ASIHttpRequest • LRResty • AFNetworking • RestKitFriday, 16 September 11
    • LRRestyFriday, 16 September 11
    • LRResty Performing a GET request - (IBAction)search { [[LRResty client] get:@"http://rmit-property-search.heroku.com/search" delegate:self]; }Friday, 16 September 11
    • LRResty Performing a GET request - (IBAction)search { [[LRResty client] get:@"http://rmit-property-search.heroku.com/search" delegate:self]; } Receiving the delegate callback - (void)restClient:(LRRestyClient *)client receivedResponse:(LRRestyResponse *)response; { NSData *data = [response responseData]; // convert data to property objects }Friday, 16 September 11
    • Parsing dataFriday, 16 September 11
    • Parsing data Don’t reinvent the wheelFriday, 16 September 11
    • Parsing data Don’t reinvent the wheel • JSONKit • json framework • YAJLFriday, 16 September 11
    • Parsing data Don’t reinvent the wheel • JSONKit • json framework • YAJLFriday, 16 September 11
    • YAJLFriday, 16 September 11
    • YAJL Converting NSString or NSData to JSON - (id)yajl_JSON;Friday, 16 September 11
    • YAJL Converting NSString or NSData to JSON - (id)yajl_JSON; Extracting property data NSDictionary *jsonDict = [data yajl_JSON]; NSArray *propertiesArray = [jsonDict valueForKey:@"properties"]; NSMutableArray *newProperties = [NSMutableArray array]; for (NSDictionary *dict in propertiesArray) { Property *property = [Property propertyWithDictionary:dict]; [newProperties addObject:property]; }Friday, 16 September 11
    • YAJL Converting NSString or NSData to JSON - (id)yajl_JSON; Extracting property data NSDictionary *jsonDict = [data yajl_JSON]; NSArray *propertiesArray = [jsonDict valueForKey:@"properties"]; NSMutableArray *newProperties = [NSMutableArray array]; for (NSDictionary *dict in propertiesArray) { Property *property = [Property propertyWithDictionary:dict]; [newProperties addObject:property]; }Friday, 16 September 11
    • NSDictionary -> PropertyFriday, 16 September 11
    • NSDictionary -> Property Pull the values you want out of the dictionary+ (Property *)propertyWithDictionary:(NSDictionary *)dict{ return [Property propertyWithAddess:[dict valueForKey:@"address"] suburb:[dict valueForKey:@"suburb"] postcode:[dict valueForKey:@"postcode"] photo:[dict valueForKey:@"photo"] summary:[dict valueForKey:@"summary"]];}Friday, 16 September 11
    • Demo 3: Dynamic contentFriday, 16 September 11
    • 4. Master/detail navigationFriday, 16 September 11
    • DetailViewControllerFriday, 16 September 11
    • Creating the new view controller with a propertyFriday, 16 September 11
    • Creating the new view controller with a property - (id)initWithProperty:(Property *)aProperty { if ((self = [super initWithNibName:@"DetailViewController" bundle:nil])) { self.property = aProperty; self.title = @"Property"; } return self; }Friday, 16 September 11
    • Updating content in the DetailViewControllerFriday, 16 September 11
    • Updating content in the DetailViewController - (void)viewDidLoad; { [super viewDidLoad]; self.address.text = self.property.address; self.location.text = self.property.location; self.photo.image = self.property.photo; self.summary.text = self.property.summary; }Friday, 16 September 11
    • UITableViewDelegate - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;Friday, 16 September 11
    • UITableViewDelegate - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath; • pull out the Property object for selected row • create a new DetailViewController with that Property • push the new controller onto the navigation stackFriday, 16 September 11
    • Demo 4: Master / DetailFriday, 16 September 11
    • 5. Make it awesomeFriday, 16 September 11
    • What’s missing?Friday, 16 September 11
    • What’s missing? • Can’t dismiss the keyboardFriday, 16 September 11
    • What’s missing? • Can’t dismiss the keyboard • Search does not actually searchFriday, 16 September 11
    • What’s missing? • Can’t dismiss the keyboard • Search does not actually search • No progress indicator while loadingFriday, 16 September 11
    • What’s missing? • Can’t dismiss the keyboard • Search does not actually search • No progress indicator while loading • People like pull-to-refresh like FacebookFriday, 16 September 11
    • Demo 5: Making it awesomeFriday, 16 September 11
    • The finished productFriday, 16 September 11
    • The finished productFriday, 16 September 11
    • Master/detail navigationFriday, 16 September 11
    • Summary 1. Basic table views 2. Custom table views 3. Dynamic content 4. Master/detail navigation 5. Make it awesomeFriday, 16 September 11
    • iPhone App Case Study Stewart Gleadow g sgleadow@thoughtworks.comFriday, 16 September 11
    • AppendixFriday, 16 September 11
    • Links • https://github.com/lukeredpath/LRResty • http://gabriel.github.com/yajl-objc/ • https://github.com/jdg/MBProgressHUD • https://github.com/chpwn/PullToRefreshView • http://www.heroku.com/ • http://www.sinatrarb.com/Friday, 16 September 11
    • Linking static libraries and frameworksFriday, 16 September 11
    • Linking static libraries and frameworks Other linker flags: -all_load -ObjCFriday, 16 September 11