View
2.231
Download
1
Category
Tags:
Preview:
DESCRIPTION
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.
Citation preview
@MicheleTitolo
API Jonesand the
Wireframes of Doom
APIs & Wireframes
APIs
Wireframes
Not mockups
Wireframes
What not to do
Hey, look! A Wireframe!
Start developing!
Models
//// 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
//// 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
//// 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
PhotoCell
//// 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
//// 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
//// 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
...several hours to several days later...
Build and Run
Time === Money
The right way
Hey, look! A Wireframe!
Annotations
photo posted date
photo
users who love photo
user picture, name
photo comments
photo location
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
Write it down.
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)
JSON
{! "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" } ] } ]}
Back to the list
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)
{! "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 ],
Congrats!You found a problem.
Make a note,then move along
Do this for every screen.
Measure twice, cut once
Measure twice, cut once
Communicate!
Work...uninterrupted
Tips & Tricks
Design
Pull To Refresh
To remove all data, or not to remove all data, that is the
question
Storage
Don’t overwrite data with nil
//// NSMutableDictionary+NilAdditions.m//
@implementation NSMutableDictionary (NilAdditions)
- (void)setNotNilObject:(id)anObject forKey:(id<NSCopying>)key{ if (anObject) { [self setObject:anObject forKey:key]; }}
@end
Infinite Scroll
Pagination
Remember your place
Drill Down
REST
GET /resources
GET /resources/:id
GET /resources/:id/nested_resources
GET /photos
GET /photos/55
GET /photos/55/comments
REST has it’s problems, too
APIs
Find Patterns
Meta information
Structures
Inconsistencies
Missing or Bad Data
Getting the Data
Batching
GET /photos/55
GET /photos/55/comments
Make sure you are actually loading data
“comment_count”
“total_items”
Background Processing
Blocking the main thread is bad
Process & construct whereit won’t affect performance
Caching
Core Data
NSCache
Documentation
Agile
This can be done
More communication,faster turnaround
Define “iteration”
In Summary
Plan Ahead
Work smart, not hard
Why’d it have to be snakes?
Thank you!
@MicheleTitolo
Recommended