Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

API Jones and the Wireframes of Doom

2,921 views

Published on

When you look at a wireframe, what do you see? ViewControllers, navigation bars, and tableviews? As developers, we are great at figuring out what to put on the screen, what to animate, and how to put those pieces together. What we don't realize, in this early stage of app development, is that knowing your APIs here is crucial. How many times have we gone to implement a feature, only to find a half-baked API, or one that makes us hardcode half the information? The wireframe stage is the point to match screens with API calls, because this is where the app is most flexible. In this session we will walk through how to match wireframes to their corresponding APIs, as well as identify and solve the problems they create.

Published in: Technology, Business
  • Be the first to comment

  • Be the first to like this

API Jones and the Wireframes of Doom

  1. 1. @MicheleTitolo API Jones and the Wireframes of Doom
  2. 2. APIs & Wireframes
  3. 3. APIs
  4. 4. Wireframes
  5. 5. Not mockups
  6. 6. Wireframes
  7. 7. What not to do
  8. 8. Hey, look! A Wireframe!
  9. 9. Start developing!
  10. 10. Models
  11. 11. // // Photo.h // @interface Photo : NSObject @property (strong, nonatomic) User* user; @property (strong, nonatomic) Location* location; @property (strong, nonatomic) NSNumber* photoID; @property (strong, nonatomic) NSDate* timestamp; @property (strong, nonatomic) NSSet* comments; @property (strong, nonatomic) NSURL* photoURL; @end
  12. 12. // // User.h // @interface User : NSObject @property (copy, nonatomic) NSString* username; @property (strong, nonatomic) NSNumber* userID; @property (strong, nonatomic) NSURL* userPhotoURL; @property (strong, nonatomic) NSSet* photos; @property (strong, nonatomic) NSSet* comments; @end
  13. 13. // // Comment.h // @interface Comment : NSObject @property (strong, nonatomic) User* user; @property (strong, nonatomic) Photo* photo; @property (strong, nonatomic) NSDate* timestamp; @property (copy, nonatomic) NSString* text; @end
  14. 14. PhotoCell
  15. 15. // // PhotoCell.h // @interface PhotoCell : UITableViewCell @property (weak, nonatomic) IBOutlet UIImageView* userImageView; @property (weak, nonatomic) IBOutlet UIImageView* photoImageView; @property (weak, nonatomic) IBOutlet UILabel* userNameLabel; @property (weak, nonatomic) IBOutlet UILabel* dateLabel; @property (weak, nonatomic) IBOutlet UILabel* locationLabel; @property (weak, nonatomic) IBOutlet UILabel* usersLovedLabel; @property (weak, nonatomic) IBOutlet UILabel* userCommentLabel; @property (strong, nonatomic) Photo* cellPhoto; - (void)setupWithPhoto:(Photo*)photo; @end
  16. 16. // // PhotoCell.m // @implementation PhotoCell - (void)setupWithPhoto:(Photo *)photo { self.cellPhoto = photo; [self.userImageView setImageWithURL:photo.user.userPhotoURL]; [self.photoImageView setImageWithURL:photo.photoURL]; self.userNameLabel.text = photo.user.username; // etc. } @end
  17. 17. // // PhotoViewController.m // @implementation PhotoViewController - (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath { PhotoCell* cell = [tableView dequeueReusableCellWithIdentifier:s_cellID forIndexPath:indexPath]; Photo* photo = [self.photos objectAtIndex:indexPath.row]; [cell setupWithPhoto:photo]; return cell; } @end
  18. 18. ...several hours to several days later...
  19. 19. Build and Run
  20. 20. Time === Money
  21. 21. The right way
  22. 22. Hey, look! A Wireframe!
  23. 23. Annotations
  24. 24. photo posted date photo users who love photo user picture, name photo comments photo location
  25. 25. photo posted date photo users who love photo user picture, name photo comments photo location tapping goes to user profile tapping goes to user profile tapping goes to location on map tapping user goes to user profile
  26. 26. Write it down.
  27. 27. Photo • location (lat/log and name) • timestamp • image URL • user (name, photo, and id) • comments (text, user name, and user id) • users who love (name and id)
  28. 28. JSON
  29. 29. { ! "meta": { ! ! "self":"photos", ! ! "page":1, ! ! "offset":0, ! ! "total_items":282 ! }, ! "photos": [ { "photo_url":"http://p3.amazons3.com/apijones/photos/124hh3b99d77dsnn.png", "created_at":"2013-09-01T18:16:54Z", "identifier":24435, "user": { "username":"karlthefog", "identifier":6332 }, "loves": [ 5622, 4402, 9773 ], "comments": [ { "text":"Sorry I'm not home right now", "user_id":24254, "identifier":122887, "timestamp":"2013-09-01T18:36:02Z" }, { "text":"I'm floating into spiderwebs", "user_id":6332, "identifier":122921, "timestamp":"2013-09-01T18:42:22Z" } ] } ] }
  30. 30. Back to the list
  31. 31. Photo • location (lat/log and name) • timestamp • image URL • user (name, photo, and id) • comments (text, user name, and user id) • users who love (name and id)(name and id)
  32. 32. { ! "meta": { ! ! "self":"photos", ! ! "page":1, ! ! "offset":0, ! ! "total_items":282 ! }, ! "photos": [ { "photo_url":"http://p3.amazons3.com/apijones/photos/124hh3b99d77dsnn.png", "created_at":"2013-09-01T18:16:54Z", "identifier":24435, "user": { "username":"karlthefog", "identifier":6332 }, "loves": [ 5622, 4402, 9773 ], "comments": [ { "text":"Sorry I'm not home right now", "user_id":24254, "identifier":122887, "timestamp":"2013-09-01T18:36:02Z" }, { "text":"I'm floating into spiderwebs", "user_id":6332, "identifier":122921, "timestamp":"2013-09-01T18:42:22Z" } ] } ] } "loves": [ 5622, 4402, 9732 ],
  33. 33. Congrats! You found a problem.
  34. 34. Make a note, then move along
  35. 35. Do this for every screen.
  36. 36. Measure twice, cut once
  37. 37. Measure twice, cut once
  38. 38. Communicate!
  39. 39. Work...uninterrupted
  40. 40. Tips & Tricks
  41. 41. Design
  42. 42. Pull To Refresh
  43. 43. To remove all data, or not to remove all data, that is the question
  44. 44. Storage
  45. 45. Don’t overwrite data with nil
  46. 46. // // NSMutableDictionary+NilAdditions.m // @implementation NSMutableDictionary (NilAdditions) - (void)setNotNilObject:(id)anObject forKey:(id<NSCopying>)key { if (anObject) { [self setObject:anObject forKey:key]; } } @end
  47. 47. Infinite Scroll
  48. 48. Pagination
  49. 49. Remember your place
  50. 50. Drill Down
  51. 51. REST
  52. 52. GET /resources GET /resources/:id GET /resources/:id/nested_resources
  53. 53. GET /photos GET /photos/55 GET /photos/55/comments
  54. 54. REST has it’s problems, too
  55. 55. APIs
  56. 56. Find Patterns
  57. 57. Meta information
  58. 58. Structures
  59. 59. Inconsistencies
  60. 60. Missing or Bad Data
  61. 61. Getting the Data
  62. 62. Batching
  63. 63. GET /photos/55 GET /photos/55/comments
  64. 64. Make sure you are actually loading data
  65. 65. “comment_count” “total_items”
  66. 66. Background Processing
  67. 67. Blocking the main thread is bad
  68. 68. Process & construct where it won’t affect performance
  69. 69. Caching
  70. 70. Core Data
  71. 71. NSCache
  72. 72. Documentation
  73. 73. Agile
  74. 74. This can be done
  75. 75. More communication, faster turnaround
  76. 76. Define “iteration”
  77. 77. In Summary
  78. 78. Plan Ahead
  79. 79. Work smart, not hard
  80. 80. Why’d it have to be snakes?
  81. 81. Thank you! @MicheleTitolo

×