Successfully reported this slideshow.

iOS app case study

12

Share

Upcoming SlideShare
Beginning iPhone Development
Beginning iPhone Development
Loading in …3
×
1 of 105
1 of 105

More Related Content

Related Books

Free with a 14 day trial from Scribd

See all

Related Audiobooks

Free with a 14 day trial from Scribd

See all

iOS app case study

  1. 1. iPhone App Case Study Stewart Gleadow sgleadow@thoughtworks.com @stewgleadow Friday, 16 September 11
  2. 2. Why iPhone development? Friday, 16 September 11
  3. 3. YOW Conference • Workshops November 28-30 • Conference December 1-2 • http://www.yowconference.com.au/ • lisa@yowconference.com Friday, 16 September 11
  4. 4. Common features in iPhone apps Friday, 16 September 11
  5. 5. Outline 1. Basic table views 2. Custom table views 3. Dynamic content 4. Master/detail navigation 5. Make it awesome Friday, 16 September 11
  6. 6. Games Friday, 16 September 11
  7. 7. Camera control Friday, 16 September 11
  8. 8. Basic tables Friday, 16 September 11
  9. 9. Advanced tables Friday, 16 September 11
  10. 10. Forms Friday, 16 September 11
  11. 11. Scroll views Friday, 16 September 11
  12. 12. Maps Friday, 16 September 11
  13. 13. Location awareness Friday, 16 September 11
  14. 14. Master/detail navigation Friday, 16 September 11
  15. 15. Master/detail navigation Friday, 16 September 11
  16. 16. Consuming and presenting information from the web Friday, 16 September 11
  17. 17. Build up your toolbox Friday, 16 September 11
  18. 18. Build up your toolbox http://cocoawithlove.com/2011/06/process-of-writing-ios-application.html Friday, 16 September 11
  19. 19. Build up your toolbox http://cocoawithlove.com/2011/06/process-of-writing-ios-application.html Friday, 16 September 11
  20. 20. 1. Basic table view Friday, 16 September 11
  21. 21. Property An Objective C domain model class Friday, 16 September 11
  22. 22. 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 Friday, 16 September 11
  23. 23. 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 classes Friday, 16 September 11
  24. 24. Property Make your objects easy to create and configure Friday, 16 September 11
  25. 25. 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
  26. 26. UIViewController UITableView Friday, 16 September 11
  27. 27. UIViewController UITableView UITableViewDataSource UITableViewDelegate UITableViewCell Friday, 16 September 11
  28. 28. UITableView Friday, 16 September 11
  29. 29. UITableView Creating your UITableView UITableView *table; table = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain]; Friday, 16 September 11
  30. 30. 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
  31. 31. 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
  32. 32. UITableView Friday, 16 September 11
  33. 33. UITableView Friday, 16 September 11
  34. 34. UITableViewCell Friday, 16 September 11
  35. 35. UITableViewCell Creating a table cell - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier; Friday, 16 September 11
  36. 36. UITableViewCell Creating a table cell - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier; [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"RMITCellIdentifier"]; Friday, 16 September 11
  37. 37. UITableViewCell Creating a table cell - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier; [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"RMITCellIdentifier"]; Reuse is important Friday, 16 September 11
  38. 38. 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
  39. 39. UITableViewDataSource Friday, 16 September 11
  40. 40. UITableViewDataSource How many sections do I have? Friday, 16 September 11
  41. 41. UITableViewDataSource How many sections do I have? - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView; Friday, 16 September 11
  42. 42. UITableViewDataSource How many sections do I have? - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView; How many rows are in each section? Friday, 16 September 11
  43. 43. 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
  44. 44. 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
  45. 45. 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
  46. 46. Demo 1: Basic table view Friday, 16 September 11
  47. 47. 2. Custom table view Friday, 16 September 11
  48. 48. UITableViewCell textLabel imageView detailTextLabel Friday, 16 September 11
  49. 49. UITableViewCell textLabel imageView detailTextLabel Plus: • backgroundView • selectedBackgroundView • contentView Friday, 16 September 11
  50. 50. 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
  51. 51. 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
  52. 52. 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 class Friday, 16 September 11
  53. 53. PropertyCell A subclass of UITableViewcell Friday, 16 September 11
  54. 54. 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
  55. 55. Demo 2: Custom table view Friday, 16 September 11
  56. 56. 3. Dynamic content Friday, 16 September 11
  57. 57. Backend server • Hosted on Heroku • http://rmit-property-search.heroku.com/search • Written in Ruby • Uses the Sinatra framework Friday, 16 September 11
  58. 58. Server code Friday, 16 September 11
  59. 59. Server code require 'rubygems' require 'bundler' require 'erb' Bundler.require get '/search' do @search = params[:q] erb :properties end Friday, 16 September 11
  60. 60. Server code require 'rubygems' require 'bundler' require 'erb' Bundler.require get '/search' do @search = params[:q] template erb :properties end JSON file Friday, 16 September 11
  61. 61. Example JSON Friday, 16 September 11
  62. 62. 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
  63. 63. Networking Friday, 16 September 11
  64. 64. Networking Don’t reinvent the wheel Friday, 16 September 11
  65. 65. Networking Don’t reinvent the wheel • NSURLConnection • ASIHttpRequest • LRResty • AFNetworking • RestKit Friday, 16 September 11
  66. 66. Networking Don’t reinvent the wheel • NSURLConnection • ASIHttpRequest • LRResty • AFNetworking • RestKit Friday, 16 September 11
  67. 67. LRResty Friday, 16 September 11
  68. 68. LRResty Performing a GET request - (IBAction)search { [[LRResty client] get:@"http://rmit-property-search.heroku.com/search" delegate:self]; } Friday, 16 September 11
  69. 69. 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
  70. 70. Parsing data Friday, 16 September 11
  71. 71. Parsing data Don’t reinvent the wheel Friday, 16 September 11
  72. 72. Parsing data Don’t reinvent the wheel • JSONKit • json framework • YAJL Friday, 16 September 11
  73. 73. Parsing data Don’t reinvent the wheel • JSONKit • json framework • YAJL Friday, 16 September 11
  74. 74. YAJL Friday, 16 September 11
  75. 75. YAJL Converting NSString or NSData to JSON - (id)yajl_JSON; Friday, 16 September 11
  76. 76. 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
  77. 77. 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
  78. 78. NSDictionary -> Property Friday, 16 September 11
  79. 79. 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
  80. 80. Demo 3: Dynamic content Friday, 16 September 11
  81. 81. 4. Master/detail navigation Friday, 16 September 11
  82. 82. DetailViewController Friday, 16 September 11
  83. 83. Creating the new view controller with a property Friday, 16 September 11
  84. 84. 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
  85. 85. Updating content in the DetailViewController Friday, 16 September 11
  86. 86. 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
  87. 87. UITableViewDelegate - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath; Friday, 16 September 11
  88. 88. 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 stack Friday, 16 September 11
  89. 89. Demo 4: Master / Detail Friday, 16 September 11
  90. 90. 5. Make it awesome Friday, 16 September 11
  91. 91. What’s missing? Friday, 16 September 11
  92. 92. What’s missing? • Can’t dismiss the keyboard Friday, 16 September 11
  93. 93. What’s missing? • Can’t dismiss the keyboard • Search does not actually search Friday, 16 September 11
  94. 94. What’s missing? • Can’t dismiss the keyboard • Search does not actually search • No progress indicator while loading Friday, 16 September 11
  95. 95. 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
  96. 96. Demo 5: Making it awesome Friday, 16 September 11
  97. 97. The finished product Friday, 16 September 11
  98. 98. The finished product Friday, 16 September 11
  99. 99. Master/detail navigation Friday, 16 September 11
  100. 100. Summary 1. Basic table views 2. Custom table views 3. Dynamic content 4. Master/detail navigation 5. Make it awesome Friday, 16 September 11
  101. 101. iPhone App Case Study Stewart Gleadow g sgleadow@thoughtworks.com Friday, 16 September 11
  102. 102. Appendix Friday, 16 September 11
  103. 103. 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
  104. 104. Linking static libraries and frameworks Friday, 16 September 11
  105. 105. Linking static libraries and frameworks Other linker flags: -all_load -ObjC Friday, 16 September 11

×