ios app case study
DESCRIPTION
The slides from a lecture I gave at RMIT doing a case study of a simple property search application.TRANSCRIPT
Why iPhone development?
Friday, 16 September 11
YOW Conference
• Workshops November 28-30
• Conference December 1-2
• http://www.yowconference.com.au/
Friday, 16 September 11
Common featuresin iPhone apps
Friday, 16 September 11
Outline
1. Basic table views
2. Custom table views
3. Dynamic content
4. Master/detail navigation
5. Make it awesome
Friday, 16 September 11
Games
Friday, 16 September 11
Camera control
Friday, 16 September 11
Basic tables
Friday, 16 September 11
Advanced tables
Friday, 16 September 11
Forms
Friday, 16 September 11
Scroll views
Friday, 16 September 11
Maps
Friday, 16 September 11
Location awareness
Friday, 16 September 11
Master/detail navigation
Friday, 16 September 11
Master/detail navigation
Friday, 16 September 11
Consuming and presenting information
from the web
Friday, 16 September 11
Build up your toolbox
Friday, 16 September 11
Build up your toolbox
http://cocoawithlove.com/2011/06/process-of-writing-ios-application.html
Friday, 16 September 11
Build up your toolbox
http://cocoawithlove.com/2011/06/process-of-writing-ios-application.html
Friday, 16 September 11
1. Basic table view
Friday, 16 September 11
PropertyAn Objective C domain model class
Friday, 16 September 11
PropertyAn 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
Friday, 16 September 11
PropertyAn 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 classes
Friday, 16 September 11
PropertyMake your objects easy to create and configure
Friday, 16 September 11
PropertyMake 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
UITableView
UIViewController
Friday, 16 September 11
UITableView
UIViewController
UITableViewDataSource
UITableViewDelegate
UITableViewCell
Friday, 16 September 11
UITableView
Friday, 16 September 11
UITableView *table;table = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
Creating your UITableView
UITableView
Friday, 16 September 11
UITableView *table;table = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
table.delegate = self;table.dataSource = self;
Creating your UITableView
Setting up your delegates
UITableView
Friday, 16 September 11
UITableView *table;table = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
[self.view addSubview:table];
table.delegate = self;table.dataSource = self;
Creating your UITableView
Setting up your delegates
Adding the table to the view
UITableView
Friday, 16 September 11
UITableView
Friday, 16 September 11
UITableView
Friday, 16 September 11
UITableViewCell
Friday, 16 September 11
UITableViewCell
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier;
Creating a table cell
Friday, 16 September 11
UITableViewCell
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier;
Creating a table cell
[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"RMITCellIdentifier"];
Friday, 16 September 11
UITableViewCell
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier;
Creating a table cell
[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"RMITCellIdentifier"];
Reuse is important
Friday, 16 September 11
UITableViewCell
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier;
Creating a table cell
[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"RMITCellIdentifier"];
Reuse is important
Configuring the cellcell.textLabel.text = @"title string";cell.detailTextLabel.text = @"subtitle string";
Friday, 16 September 11
UITableViewDataSource
Friday, 16 September 11
UITableViewDataSourceHow many sections do I have?
Friday, 16 September 11
UITableViewDataSourceHow many sections do I have?
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView;
Friday, 16 September 11
UITableViewDataSourceHow many sections do I have?
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView;
How many rows are in each section?
Friday, 16 September 11
UITableViewDataSourceHow 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
UITableViewDataSourceHow 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
- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
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
Demo 1:Basic table view
Friday, 16 September 11
2. Custom table view
Friday, 16 September 11
UITableViewCell
textLabelimageView
detailTextLabel
Friday, 16 September 11
UITableViewCell
textLabelimageView
detailTextLabel
• backgroundView
• selectedBackgroundView
• contentView
Plus:
Friday, 16 September 11
Customising Cellsif (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 Cellsif (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 Cellsif (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 class
Friday, 16 September 11
PropertyCellA subclass of UITableViewcell
Friday, 16 September 11
PropertyCellA 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 view
Friday, 16 September 11
3. Dynamic content
Friday, 16 September 11
Backend server
• Hosted on Heroku
• http://rmit-property-search.heroku.com/search
• Written in Ruby
• Uses the Sinatra framework
Friday, 16 September 11
Server code
Friday, 16 September 11
Server code
require 'rubygems'require 'bundler'require 'erb'Bundler.require
get '/search' do @search = params[:q] erb :propertiesend
Friday, 16 September 11
Server code
require 'rubygems'require 'bundler'require 'erb'Bundler.require
get '/search' do @search = params[:q] erb :propertiesend
templateJSON file
Friday, 16 September 11
Example JSON
Friday, 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
Networking
Friday, 16 September 11
Don’t reinvent the wheel
Networking
Friday, 16 September 11
Don’t reinvent the wheel
• NSURLConnection
• ASIHttpRequest
• LRResty
• AFNetworking
• RestKit
Networking
Friday, 16 September 11
Don’t reinvent the wheel
• NSURLConnection
• ASIHttpRequest
• LRResty
• AFNetworking
• RestKit
Networking
Friday, 16 September 11
LRResty
Friday, 16 September 11
Performing a GET request
LRResty
- (IBAction)search{ [[LRResty client] get:@"http://rmit-property-search.heroku.com/search" delegate:self];}
Friday, 16 September 11
Performing a GET request
- (void)restClient:(LRRestyClient *)client receivedResponse:(LRRestyResponse *)response;{ NSData *data = [response responseData]; // convert data to property objects}
LRResty
Receiving the delegate callback
- (IBAction)search{ [[LRResty client] get:@"http://rmit-property-search.heroku.com/search" delegate:self];}
Friday, 16 September 11
Parsing data
Friday, 16 September 11
Don’t reinvent the wheel
Parsing data
Friday, 16 September 11
Don’t reinvent the wheel
• JSONKit
• json framework
• YAJL
Parsing data
Friday, 16 September 11
Don’t reinvent the wheel
• JSONKit
• json framework
• YAJL
Parsing data
Friday, 16 September 11
YAJL
Friday, 16 September 11
Converting NSString or NSData to JSON
YAJL
- (id)yajl_JSON;
Friday, 16 September 11
Converting NSString or NSData to JSON
YAJL
- (id)yajl_JSON;
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];}
Extracting property data
Friday, 16 September 11
Converting NSString or NSData to JSON
YAJL
- (id)yajl_JSON;
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];}
Extracting property data
Friday, 16 September 11
NSDictionary -> Property
Friday, 16 September 11
Pull the values you want out of the dictionary
NSDictionary -> Property
+ (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 content
Friday, 16 September 11
4. Master/detailnavigation
Friday, 16 September 11
DetailViewController
Friday, 16 September 11
Creating the new view controller with a property
Friday, 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 DetailViewController
Friday, 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 *)tableViewdidSelectRowAtIndexPath:(NSIndexPath *)indexPath;
Friday, 16 September 11
UITableViewDelegate- (void)tableView:(UITableView *)tableViewdidSelectRowAtIndexPath:(NSIndexPath *)indexPath;
• pull out the Property object for selected row
• create a new DetailViewController with that Property
• push the new controller onto the navigation stack
Friday, 16 September 11
Demo 4:Master / Detail
Friday, 16 September 11
5. Make it awesome
Friday, 16 September 11
What’s missing?
Friday, 16 September 11
What’s missing?
• Can’t dismiss the keyboard
Friday, 16 September 11
What’s missing?
• Can’t dismiss the keyboard
• Search does not actually search
Friday, 16 September 11
What’s missing?
• Can’t dismiss the keyboard
• Search does not actually search
• No progress indicator while loading
Friday, 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 Facebook
Friday, 16 September 11
Demo 5:Making it awesome
Friday, 16 September 11
The finished product
Friday, 16 September 11
The finished product
Friday, 16 September 11
Master/detail navigation
Friday, 16 September 11
Summary
1. Basic table views
2. Custom table views
3. Dynamic content
4. Master/detail navigation
5. Make it awesome
Friday, 16 September 11
Appendix
Friday, 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 frameworks
Friday, 16 September 11
Other linker flags: -all_load -ObjC
Linking static libraries and frameworks
Friday, 16 September 11