techfest 2013 no restkit for the weary
DESCRIPTION
This is the deck the accompanied my talk on RESTKit (the RESTful web service framework for iOS) that I gave at Tulsa Techfest 2013.TRANSCRIPT
No RestKit for the Weary
Matt GallowayArchitactile
Tuesday, January 28, 14
Some Amazingly Cool Data from the “Cloud”
the “Cloud”RESTFul* Web
Services
* By “RESTFul,“ of course, I mean REST-ish and JSONy.
Tuesday, January 28, 14
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error- (void)connectionDidFinishLoading:(NSURLConnection *)connection
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];[[NSURLConnection alloc] initWithRequest:request delegate:self];
Web Service Calls on iOS
NSString *url = @”http://somewebservice.com/objects.json”;
Define your URL
Make the Call
Then implement all of these delegate methods!!!
and now you have to parse the JSON in NSData into something useful...
Tuesday, January 28, 14
-(void) parseJSONIntoModel:(NSData *) jsonData { NSError *error = nil; NSDictionary *json = [NSJSONSerialization JSONObjectWithData:jsonData
options:NSJSONReadingAllowFragments error:&error];
if (error!=nil) { // TODO: Insert annoying JSON error handler here. } if ([json isKindOfClass:[NSArray class]]) { //TODO: Uh. I was expecting a dictionary but apparently this is an array. Writng some handling code here. } for(NSString *key in [json allKeys]) { if ([key isEqualToString:@"user"]) { NSDictionary *userDictionary = [json objectForKey:key]; NSNumber *userId = [userDictionary objectForKey:@"id"]; RKGUser *user = [[ObjectFactory sharedFactory] userForUserId:userId]; if (user==nil) { user = [[ObjectFactory sharedFactory] newUser]; user.userId=useriD; } user.name = [userDictionary objectForKey:@"name"]; user.username = [userDictionary objectForKey:@"username"]; user.phone = [userDictionary objectForKey:@"phone"]; user.email = [userDictionary objectForKey:@"email"]; } . . .
NSJSONSerialization is great, but...
Tuesday, January 28, 14
Enter RestKithttps://github.com/RestKit/RestKit/
RestKit is a framework for consuming and modeling
RESTful web resources on iOS and OS X
Tuesday, January 28, 14
[[RKObjectManager sharedManager] getObjectsAtPath:@"objects.json" parameters:nil success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) { // Call is successful. Objects are all populated. } failure:^(RKObjectRequestOperation *operation, NSError *error) { // Call failed.
}];
Tuesday, January 28, 14
* Open Source & available on GitHub
* Built on AFNetworking
* Beautifully multi-threaded
* Integrates seamlessly with CoreData
* Also works with plain objects
* Handles relationships, nesting, etc.
* Based on mapping like an ORM
* Very configurable
* Handles all REST verbs - GET, POST, PATCH, etc.
* Very actively maintained
* A bunch of other stuff - database seeding, search,
XML, etc.
RestKit is...
Tuesday, January 28, 14
Installing RestKit
I <3 CocoaPods$ cd /path/to/MyProject$ touch Podfile$ edit Podfileplatform :ios, '5.0' # Or platform :osx, '10.7'pod 'RestKit', '~> 0.20.0'
$ pod install$ open MyProject.xcworkspace
Tuesday, January 28, 14
Using RestKit: The Web Service
Tuesday, January 28, 14
Using RestKit: The Object
@interface Joke : NSObject
@property (nonatomic, strong) NSNumber *jokeId;@property (nonatomic, strong) NSString *text;
@end
@implementation Joke@end
Tuesday, January 28, 14
Using RestKit: The Setup
-(void) setupRestKit { RKObjectManager *objectManager = [RKObjectManager managerWithBaseURL:[NSURL URLWithString:@"http://api.icndb.com/"]]; objectManager.requestSerializationMIMEType=RKMIMETypeJSON; [RKObjectManager setSharedManager:objectManager];
.
.
.
(There are a few extra steps for CoreData, authentication, etc.)
Tuesday, January 28, 14
Using RestKit: The Mapping
RKObjectMapping *jokeMapping = [RKObjectMapping mappingForClass:[Joke class]];
[jokeMapping addAttributeMappingsFromDictionary:@{ @"id": @"jokeId", @"joke": @"text"}];
RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:jokeMapping method:RKRequestMethodGET pathPattern:@"jokes"
keyPath:@"value" statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
[[RKObjectManager sharedManager] addResponseDescriptor:responseDescriptor];
Tuesday, January 28, 14
I <3 Singletons
RKObjectManager is a singleton, so
the setup and mapping steps need
only be done once, usually at app
launch.
Set it and forget it. :)
Tuesday, January 28, 14
Using RestKit: The Call
[[RKObjectManager sharedManager] getObjectsAtPath:@"jokes" parameters:nil success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) { self.jokes = mappingResult.array; [self.tableView reloadData]; } failure:^(RKObjectRequestOperation *operation, NSError *error) { [self displayError:error];
}];
RKMappingResult has count,firstObject, array, dictionary, and set properties
Tuesday, January 28, 14
Using RestKit: The Mapping for POST
RKObjectMapping *inverseJokeMapping = [jokeMapping inverseMapping]; RKRequestDescriptor *requestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping:inverseJokeMapping objectClass:[Joke class] rootKeyPath:@"jokes" method:RKRequestMethodPOST ];
[[RKObjectManager sharedManager] addRequestDescriptor:requestDescriptor];
Tuesday, January 28, 14
Using RestKit: POSTing
Joke *aJoke=[[Joke alloc] init]; aJoke.jokeId=@9999; aJoke.text=@"Chuck Norris can find the end of a circle."; [[RKObjectManager sharedManager] postObject:aJoke path:@"jokes" parameters:nil success:^(RKObjectRequestOperation *operation,
RKMappingResult *mappingResult){} failure:^(RKObjectRequestOperation *operation, NSError *error){}];
Tuesday, January 28, 14
Some Demos
Tuesday, January 28, 14
Matt GallowayArchitactile
Tuesday, January 28, 14