RestKitFrom Zero to Hero
Peter Friese, Zühlke Engineering
What we will cover today
1
2
3
Challenges
How can RestKit help?
Demos!
Challenges...
Flaky Connectivity
Challenges...
Flaky Connectivity
Different Data Formats
Challenges...
Flaky Connectivity
Different Data Formats
Offline Data Access
2
How can RestKit help?
RestKit Features
Integrated HTTP Stack
Pluggable Parser
Object Mapping
Core Data Integration
Integrated HTTP Stack
// create clientRKClient *client = [RKClient clientWithBaseURL:@"http://github.org"];
// send this field with each request[client setValue:[[UIDevice currentDevice] uniqueIdentifier] forHTTPHeaderField:@"UDID"];
Integrated HTTP Stack
- (IBAction)forkYou:(id)sender { [[RKClient sharedClient]
get:@"https://github.com/fluidicon.png" delegate:self];
}
- (void)request:(RKRequest *)request didLoadResponse:(RKResponse *)response
{ if ([response isSuccessful]) { UIImage *image =
[UIImage imageWithData:[response body]]; self.imageView.image = image; }}
Integrated HTTP StackPluggable Parser Object Mapping
JSON(new and cool)
XML(legacy)
Integrated HTTP StackPluggable Parser Object Mapping
#->
Integrated HTTP StackPluggable Parser Object Mapping
@interface GithubUser : NSObject
@property (strong, nonatomic) NSNumber *id;
@property (strong, nonatomic) NSString *name;
@property (strong, nonatomic) NSString *location;
@property (strong, nonatomic) NSString *followers;
@property (strong, nonatomic) NSString *email;
@property (strong, nonatomic) NSString *following;
@end
->
Integrated HTTP StackPluggable Parser Object Mapping
->RKObjectMapping *objectMapping = [RKObjectMapping mappingForClass:[GithubUser class]];
[objectMapping mapKeyPath:@"user.id" toAttribute:@"id"];[objectMapping mapKeyPath:@"user.name" toAttribute:@"name"];[objectMapping mapKeyPath:@"user.location" toAttribute:@"location"]; [objectMapping mapKeyPath:@"user.following-count" toAttribute:@"following"]; [objectMapping mapKeyPath:@"user.followers-count" toAttribute:@"followers"]
XML(legacy
)
register mapping
for a class
configure mapping (KVC)
Integrated HTTP StackPluggable Parser Object Mapping
-><user> <name>Peter Friese <following-count">36 <email>[email protected] <followers-count">42 <location>Hamburg <id>232107</user>
XML(legacy
)
@interface GithubUser@property id;@property name;@property location;@property followers;@property email;@property following;@end
(simplified code illustration, please bear with me!)
[objectMapping mapKeyPath:@"user.id" toAttribute:@"id"];
Integrated HTTP StackPluggable Parser Loading Objects
->RKObjectManager *objectManager = [RKObjectManager objectManagerWithBaseURL:@"https://github.com"];
[objectManager loadObjectsAtResourcePath:[NSString stringWithFormat:@"api/v2/xml/user/show/%@", userName]objectMapping:objectMappingdelegate:self];
- (void)objectLoader:(RKObjectLoader *)objectLoader didLoadObjects:(NSArray *)objects { GithubUser *user = [objects objectAtIndex:0];}
XML(legacy
)
can easily switch between
dev / prod
Integrated HTTP Stack Pluggable Parser
RKObjectManager *objectManager = [RKObjectManager objectManagerWithBaseURL:@"https://github.com"];
// we want to send and receive JSONobjectManager.serializationMIMEType = RKMIMETypeJSON;objectManager.acceptMIMEType = RKMIMETypeJSON;
[objectManager loadObjectsAtResourcePath:[NSString stringWithFormat:@"api/v2/json/user/show/%@", userName]objectMapping:self.mappingdelegate:self];
- (void)objectLoader:(RKObjectLoader *)objectLoader didLoadObjects:(NSArray *)objects { GithubUser *user = [objects objectAtIndex:0];}
Integrated HTTP Stack Pluggable Parser
RKObjectManager *objectManager = [RKObjectManager objectManagerWithBaseURL:@"https://github.com"];
// we want to send and receive JSONobjectManager.serializationMIMEType = RKMIMETypeJSON;objectManager.acceptMIMEType = RKMIMETypeJSON;
[objectManager loadObjectsAtResourcePath:[NSString stringWithFormat:@"api/v2/json/user/show/%@", userName]objectMapping:self.mappingdelegate:self];
- (void)objectLoader:(RKObjectLoader *)objectLoader didLoadObjects:(NSArray *)objects { GithubUser *user = [objects objectAtIndex:0];}
XML(legacy
)JSON(new
and cool
)
:-)
Integrated HTTP StackPluggable Parser Object Mapping
->RKObjectMapping *objectMapping = [RKObjectMapping mappingForClass:[GithubUser class]];
[objectMapping mapKeyPath:@"user.id" toAttribute:@"id"];[objectMapping mapKeyPath:@"user.name" toAttribute:@"name"];[objectMapping mapKeyPath:@"user.location" toAttribute:@"location"]; [objectMapping mapKeyPath:@"user.following_count" toAttribute:@"following"]; [objectMapping mapKeyPath:@"user.followers_count" toAttribute:@"followers"]
JSONregister mapping
for a class
configure mapping (KVC)
Integrated HTTP StackPluggable Parser Object Mapping
->{user: {followers_count: 42,location: "Hamburg",following_count: 36,email: “[email protected],blog: "http://www.peterfriese.de",name: "Peter Friese",id: 232107,}
}
JSON
@interface GithubUser@property id;@property name;@property location;@property followers;@property email;@property following;@end
(simplified code illustration, please bear with me!)
[objectMapping mapKeyPath:@"user.id" toAttribute:@"id"];
Integrated HTTP StackPluggable Parser Object Mapping
->Relation
ships
[issueMapping mapKeyPath:@"user" toRelationship:@"user" withMapping:userMapping];
Integrated HTTP StackPluggable Parser POSTing Objects
->
[[objectManager mappingProvider] setObjectMapping:issueMapping forKeyPath:@""];
RKObjectMapping *issueSerializationMapping = [issueMapping inverseMapping];
[[objectManager mappingProvider] setSerializationMapping:issueSerializationMapping forClass:[GithubIssue class]];
[[objectManager router] routeClass:[GithubIssue class] toResourcePath:@"/repos/:repouser/:repo/issues/:number"];
[[objectManager router] routeClass:[GithubIssue class] toResourcePath:@"/repos/:repouser/:repo/issues" forMethod:RKRequestMethodPOST ];
Integrated HTTP StackPluggable Parser POSTing Objects
->
GithubIssue *issue = [[GithubIssue alloc] init];
issue.repouser = repouser;issue.repo = repo;
[[RKObjectManager sharedManager] postObject:issue delegate:self];
Create new object
Infos for RestKit router:
POST object:
Integrated HTTP StackPluggable ParserObject Mapping Core Data Integration
Offline Data Access
Remember?
Integrated HTTP StackPluggable ParserObject Mapping Core Data Integration
Change Mapped Objects
Add a Core Data ModelRegister a Managed Object Store
Adjust Object Mappings
Adjust Object CreationFetch Data from DB / Backend
Integrated HTTP StackPluggable ParserObject Mapping Change Mapped Objects
@interface GithubUser : NSManagedObject
@interface GithubUser : NSObject
@synthesize id;@synthesize login;@synthesize name;@synthesize company;@synthesize location;@synthesize blog;@synthesize following;@synthesize followers;@synthesize email;
@dynamic id;@dynamic login;@dynamic name;@dynamic company;@dynamic location;@dynamic blog;@dynamic following;@dynamic followers;@dynamic email;
Header Header
Module Module
Integrated HTTP StackPluggable ParserObject Mapping Add a Core Data Model
Integrated HTTP StackPluggable ParserObject Mapping Add a Core Data Model
Keep in mind:Assign respective
classes to managed objects!
@interface GithubUser : NSObject
Integrated HTTP StackPluggable ParserObject Mapping Register a Managed Object Store
// set up object managerRKObjectManager *objectManager = [RKObjectManager objectManagerWithBaseURL:@"https://api.github.com"];
// set up backing data storeobjectManager.objectStore = [RKManagedObjectStore objectStoreWithStoreFilename:@"github.sqlite"];
Integrated HTTP StackPluggable ParserObject Mapping Adjust Object Mappings
RKObjectMapping *userMapping = [RKObjectMapping mappingForClass:[GithubUser class]];
RKManagedObjectMapping *userMapping = [RKManagedObjectMapping mappingForClass:[GithubUser class]];
Integrated HTTP StackPluggable ParserObject Mapping Adjust Object Creation
GithubIssue *issue = [[GithubIssue alloc] init];
GithubIssue *issue = [GithubIssue object];
Integrated HTTP StackPluggable ParserObject Mapping Fetch Data from DB / Backend
if ([[RKObjectManager sharedManager] isOnline]) {[self fetchDataFromRemote];
}else {[self fetchDataFromDataStore];
}
Online of offline?
- (void)fetchDataFromDataStore{ repos = [GithubRepo allObjects]; [self.tableView reloadData]; }
Offline - Fetch from DB
Integrated HTTP StackPluggable ParserObject Mapping Fetch Data from DB / Backend
- (void)fetchDataFromRemote{RKObjectMapping *mapping = [[[RKObjectManager sharedManager] mappingProvider] objectMappingForClass:[GithubRepo class]];
NSString *resourcePath = [NSString stringWithFormat:@"/users/%@/repos", loginInfo.login];
[[RKObjectManager sharedManager]loadObjectsAtResourcePath:resourcePath objectMapping:mappingdelegate:self];
}
Online - Fetch from Backend
Integrated HTTP StackPluggable ParserObject Mapping Fetch Data from DB / Backend
- (void)reachabilityChanged:(NSNotification*)notification {RKReachabilityObserver* observer = (RKReachabilityObserver*)[notification object];
if ([observer isNetworkReachable]) {if (![self.view isHidden]) {[self fetchDataFromRemote];
}} else {if (![self.view isHidden]) {[self fetchDataFromDataStore];
}}
}
Reconnect after offline
Integrated HTTP StackPluggable ParserObject Mapping Putting it All Together
Thanks!
Thanks!
Peter FriesePrincipal Consultant
Zühlke Engineering GmbHAm Sandtorkai 6620457 Hamburg
+49 151 108 604 72
Available for consulting,discussing all things mobileand frosty beverages
Mobile CouchDBPeter Friese
Di, 17:30 - 18:30
Auf Tuchfühlung mit smarten GerätenMasanori Fujita
Mi, 10:15 - 11:15