api jones and the wireframes of doom

Post on 10-May-2015

2.228 Views

Category:

Technology

1 Downloads

Preview:

Click to see full reader

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.

TRANSCRIPT

@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

top related