• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Introduction to Restkit
 

Introduction to Restkit

on

  • 12,775 views

Given at PDX Cocoaheads on July 27, 2011

Given at PDX Cocoaheads on July 27, 2011

Statistics

Views

Total Views
12,775
Views on SlideShare
8,657
Embed Views
4,118

Actions

Likes
13
Downloads
206
Comments
2

3 Embeds 4,118

http://petermarks.info 4115
http://www.google.com 2
http://petermarks.info&_=1323491862688 HTTP 1

Accessibility

Upload Details

Uploaded via as Apple Keynote

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel

12 of 2 previous next

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
  • I don't have RKDynamicRouter...
    Are you sure you want to
    Your message goes here
    Processing…
  • hi, if copy the slide 18, 19, 20 and 21 in my button 'Send' my User is create? really?! I haven't change something?
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment
  • Hey, I’m Peter. I’m a Cocoa and Ruby programmer and am here to talk about a tool I use called Restkit to bridge those two worlds. \n
  • \n
  • It aims to simplify communication between server and client. On one side you’ve got a server, it’s running a web app managing data in a database, it’s using a restful json or XML webservice to communicate with other programs. On the other side you have an iOS or OSX device running a native objective c application. It’s managing data in an object graph, maybe using core data. It can use Restkit to easily exchange data with the server via GET, POST, PUT and DELETE requests. \n
  • It aims to simplify communication between server and client. On one side you’ve got a server, it’s running a web app managing data in a database, it’s using a restful json or XML webservice to communicate with other programs. On the other side you have an iOS or OSX device running a native objective c application. It’s managing data in an object graph, maybe using core data. It can use Restkit to easily exchange data with the server via GET, POST, PUT and DELETE requests. \n
  • It aims to simplify communication between server and client. On one side you’ve got a server, it’s running a web app managing data in a database, it’s using a restful json or XML webservice to communicate with other programs. On the other side you have an iOS or OSX device running a native objective c application. It’s managing data in an object graph, maybe using core data. It can use Restkit to easily exchange data with the server via GET, POST, PUT and DELETE requests. \n
  • It aims to simplify communication between server and client. On one side you’ve got a server, it’s running a web app managing data in a database, it’s using a restful json or XML webservice to communicate with other programs. On the other side you have an iOS or OSX device running a native objective c application. It’s managing data in an object graph, maybe using core data. It can use Restkit to easily exchange data with the server via GET, POST, PUT and DELETE requests. \n
  • It aims to simplify communication between server and client. On one side you’ve got a server, it’s running a web app managing data in a database, it’s using a restful json or XML webservice to communicate with other programs. On the other side you have an iOS or OSX device running a native objective c application. It’s managing data in an object graph, maybe using core data. It can use Restkit to easily exchange data with the server via GET, POST, PUT and DELETE requests. \n
  • It aims to simplify communication between server and client. On one side you’ve got a server, it’s running a web app managing data in a database, it’s using a restful json or XML webservice to communicate with other programs. On the other side you have an iOS or OSX device running a native objective c application. It’s managing data in an object graph, maybe using core data. It can use Restkit to easily exchange data with the server via GET, POST, PUT and DELETE requests. \n
  • It aims to simplify communication between server and client. On one side you’ve got a server, it’s running a web app managing data in a database, it’s using a restful json or XML webservice to communicate with other programs. On the other side you have an iOS or OSX device running a native objective c application. It’s managing data in an object graph, maybe using core data. It can use Restkit to easily exchange data with the server via GET, POST, PUT and DELETE requests. \n
  • It aims to simplify communication between server and client. On one side you’ve got a server, it’s running a web app managing data in a database, it’s using a restful json or XML webservice to communicate with other programs. On the other side you have an iOS or OSX device running a native objective c application. It’s managing data in an object graph, maybe using core data. It can use Restkit to easily exchange data with the server via GET, POST, PUT and DELETE requests. \n
  • It aims to simplify communication between server and client. On one side you’ve got a server, it’s running a web app managing data in a database, it’s using a restful json or XML webservice to communicate with other programs. On the other side you have an iOS or OSX device running a native objective c application. It’s managing data in an object graph, maybe using core data. It can use Restkit to easily exchange data with the server via GET, POST, PUT and DELETE requests. \n
  • It aims to simplify communication between server and client. On one side you’ve got a server, it’s running a web app managing data in a database, it’s using a restful json or XML webservice to communicate with other programs. On the other side you have an iOS or OSX device running a native objective c application. It’s managing data in an object graph, maybe using core data. It can use Restkit to easily exchange data with the server via GET, POST, PUT and DELETE requests. \n
  • The first problem Restkit makes easier is translating different representations of the same data. You have a web service json response that lists objects using its own attribute names. In this example they’re in underscore case. Then you’ve got your Objective C model with attributes that are semantically the same, they’re just in camel case. Restkit bridges the gap with Object mapping. Restkit models provide a rosetta stone-like method that translates server attribute names to its own attribute names. This makes representing and interacting with remote objects a lot easier. \n
  • The first problem Restkit makes easier is translating different representations of the same data. You have a web service json response that lists objects using its own attribute names. In this example they’re in underscore case. Then you’ve got your Objective C model with attributes that are semantically the same, they’re just in camel case. Restkit bridges the gap with Object mapping. Restkit models provide a rosetta stone-like method that translates server attribute names to its own attribute names. This makes representing and interacting with remote objects a lot easier. \n
  • The first problem Restkit makes easier is translating different representations of the same data. You have a web service json response that lists objects using its own attribute names. In this example they’re in underscore case. Then you’ve got your Objective C model with attributes that are semantically the same, they’re just in camel case. Restkit bridges the gap with Object mapping. Restkit models provide a rosetta stone-like method that translates server attribute names to its own attribute names. This makes representing and interacting with remote objects a lot easier. \n
  • The first problem Restkit makes easier is translating different representations of the same data. You have a web service json response that lists objects using its own attribute names. In this example they’re in underscore case. Then you’ve got your Objective C model with attributes that are semantically the same, they’re just in camel case. Restkit bridges the gap with Object mapping. Restkit models provide a rosetta stone-like method that translates server attribute names to its own attribute names. This makes representing and interacting with remote objects a lot easier. \n
  • First we set up a RKClient with a base url of the web service it will be interacting with. Next, we instruct our client to send a GET request to a specific path. We set our class as the delegate and the request is sent asynchronously. When a response is received, Restkit’s object mapper uses the mappings we defined to parse the JSON or XML response body into Objective C objects. These objects are then sent to our delegate’s objectLoaderDidLoadObjects method where you can handle them by rendering to screen or whatever else. \n
  • Restkit also provides a routing system that keeps your code DRY. In that first example we had to provide the route for the resource. In REST, resources generally have the same path and it’s just the HTTP method that changes for each action. To avoid repeating resource names, we set up routes for our object manager.\n
  • Now that we’ve got our routes set up, we can use the RKObjectManager’s postObject method to create a new object on our remote web service. Again, we get a response back in the objectLoaderDidLoadObjects method. \n
  • Restkit’s object mappings provides support for Core Data managed objects as well. To do so, you must designate a primaryKeyProperty that’s semantically unique for that object. This will almost always be the server’s auto incremented database ID. Restkit uses this primary key to make sure it knows if it fetches the same object twice.\n
  • Where this core data integration really comes in handy is the mapping of relationships. Say this is a remote representation of data that corresponds to a “Project” entity in your client’s core data datamodel. It has a one to one relationship with another entity called “User” and a one to many relationship with an entity called Task”. Restkit can use it’s relationship mapping to convert the nested objects in this resource into multiple Objective C entities with relationships intact. \n
  • So here’s our interface. It’s a standard core data setup, only difference is that it inherits from RKManagedObject, which itself inherits from NSManaged Object. In our implementation, we provide an elementsToPropertyMappings dictionary and a primaryKeyProperty like we have previously. The first new thing is this elementsToRelationshipMappings relationship, which instructs the mapper to look for associated objects nested as a sub-dictionary in a JSON payload. The second new thing is the relationshipToPrimaryKeyPropertyMappings method. This instructs the mapper to connect a Core Data relationship by using the value stored in another property to lookup the target object. \n
  • So here’s our interface. It’s a standard core data setup, only difference is that it inherits from RKManagedObject, which itself inherits from NSManaged Object. In our implementation, we provide an elementsToPropertyMappings dictionary and a primaryKeyProperty like we have previously. The first new thing is this elementsToRelationshipMappings relationship, which instructs the mapper to look for associated objects nested as a sub-dictionary in a JSON payload. The second new thing is the relationshipToPrimaryKeyPropertyMappings method. This instructs the mapper to connect a Core Data relationship by using the value stored in another property to lookup the target object. \n
  • In addition to receiving entire object graphs from remote resources, we can also create entire object graphs on remote resources through relationship serialization This is actually a pet feature that I ended up implementing out of my need to POST an object with 50 to 100 children. Being able to post an object with its relationships dramatically cuts down the number of requests I need to send. \n
  • It’s worth mentioning that Restkit’s object mapping system is about to change. Everything I’ve mentioned is for the current version of 0.9.2. The upcoming version of 0.9.3 overhauls object mapping architecture. The main difference is that mappings are no longer dependent on class inheritance. This makes the mapping system a lot more flexible and light weight. All the functionality I’ve discussed will remain intact and built upon. \n\nI’d usually be concerned with such a major overhaul in architecture, but I’m reassured by the patient approach the team is taking to release this version as well the suite of unit and integration tests to measure the new version against. I know it’s probably a bad practice to present two versions of the API and I hope this doesn’t confuse people too much. I just wanted to give anyone who might implement Restkit in their project a month or so from now a heads up for what’s to come. \n
  • It’s worth mentioning that Restkit’s object mapping system is about to change. Everything I’ve mentioned is for the current version of 0.9.2. The upcoming version of 0.9.3 overhauls object mapping architecture. The main difference is that mappings are no longer dependent on class inheritance. This makes the mapping system a lot more flexible and light weight. All the functionality I’ve discussed will remain intact and built upon. \n\nI’d usually be concerned with such a major overhaul in architecture, but I’m reassured by the patient approach the team is taking to release this version as well the suite of unit and integration tests to measure the new version against. I know it’s probably a bad practice to present two versions of the API and I hope this doesn’t confuse people too much. I just wanted to give anyone who might implement Restkit in their project a month or so from now a heads up for what’s to come. \n
  • It’s worth mentioning that Restkit’s object mapping system is about to change. Everything I’ve mentioned is for the current version of 0.9.2. The upcoming version of 0.9.3 overhauls object mapping architecture. The main difference is that mappings are no longer dependent on class inheritance. This makes the mapping system a lot more flexible and light weight. All the functionality I’ve discussed will remain intact and built upon. \n\nI’d usually be concerned with such a major overhaul in architecture, but I’m reassured by the patient approach the team is taking to release this version as well the suite of unit and integration tests to measure the new version against. I know it’s probably a bad practice to present two versions of the API and I hope this doesn’t confuse people too much. I just wanted to give anyone who might implement Restkit in their project a month or so from now a heads up for what’s to come. \n
  • It’s worth mentioning that Restkit’s object mapping system is about to change. Everything I’ve mentioned is for the current version of 0.9.2. The upcoming version of 0.9.3 overhauls object mapping architecture. The main difference is that mappings are no longer dependent on class inheritance. This makes the mapping system a lot more flexible and light weight. All the functionality I’ve discussed will remain intact and built upon. \n\nI’d usually be concerned with such a major overhaul in architecture, but I’m reassured by the patient approach the team is taking to release this version as well the suite of unit and integration tests to measure the new version against. I know it’s probably a bad practice to present two versions of the API and I hope this doesn’t confuse people too much. I just wanted to give anyone who might implement Restkit in their project a month or so from now a heads up for what’s to come. \n
  • Up to this point I’ve discussed Restkit’s object mapping system, which I see as its most unique and powerful feature. Restkit also has some other cool features to smooth the process between client and server data exchange.\n
  • So looking back at the previous code we looked at to post and object and receive its response via an asynchronous callback. What’s going on quietly behind the scenes here is a class called RKRequestQueue. RKRequestQueue has three primary responsibilities: managing request memory, ensuring the network does not get overly burdened, and managing request life cycle. It enables us to post objects and recieve responses without worrying about retaining anything. It also lets us cancel requests that no longer need to be made, usually because of user action. \n
  • So looking back at the previous code we looked at to post and object and receive its response via an asynchronous callback. What’s going on quietly behind the scenes here is a class called RKRequestQueue. RKRequestQueue has three primary responsibilities: managing request memory, ensuring the network does not get overly burdened, and managing request life cycle. It enables us to post objects and recieve responses without worrying about retaining anything. It also lets us cancel requests that no longer need to be made, usually because of user action. \n
  • setting a backgroundPolicy on a request will allow the application to consume resources necessary to send and handle requests. \n
  • Restkit includes a simple interface for building multi-part requests to include things like file attachments. \n
  • You may want to ship your application to the App Store with content already available in the local store. Restkit includes a simple object seeding implementation for this purpose via the RKObjectSeeder class. It will take a JSON file you ship with your app and read it into objects just as it would a remote resource. \n
  • \n
  • \n
  • \n

Introduction to Restkit Introduction to Restkit Presentation Transcript

  • by Peter Markshttp://petermarks.info
  • Restkit is a RESTful Object Mapping Framework for iOS and OSX.
  • Server - Client
  • Server - ClientWeb Application
  • Server - ClientWeb Application Database
  • Server - Client Web Application DatabaseRESTful JSON or XML webservice
  • Server - Client Web Application Obj C Application DatabaseRESTful JSON or XML webservice
  • Server - Client Web Application Obj C Application Database Object graphRESTful JSON or XML webservice
  • Server - Client Web Application Obj C Application Database Object graphRESTful JSON or XML Restkit webservice
  • Server - Client Web Application Obj C Application Database Object graphRESTful JSON or XML Restkit webservice
  • Server - Client GET Request Web Application Obj C Application Database Object graphRESTful JSON or XML Restkit webservice
  • Server - Client GET Request Web Application Obj C Application Database Object graphRESTful JSON or XML Restkit webservice
  • Server - Client GET Request Web Application Obj C Application Database Object graph POST RequestRESTful JSON or XML Restkit webservice
  • Two representations of the same data:
  • Two representations of the same data:/contacts
  • Two representations of the same data:/contacts[{



contact:
{







id:
1234,







full_name:
Peter
Marks,







email:
petertmarks@gmail.com,



}},{



contact:
{







id:
3456,







full_name:
Barack
Obama,







email:
barack94@aol.com,



}}]
  • Two representations of the same data:/contacts @interface Contact : RKObject { NSNumber* _contactID; NSString* _fullName; NSString* _email;[{ }



contact:
{







id:
1234, @property (retain) NSNumber* contactID; @property (retain) NSString* fullName;







full_name:
Peter
Marks, @property (retain) NSString* email;







email:
petertmarks@gmail.com, @end



}},{



contact:
{







id:
3456,







full_name:
Barack
Obama,







email:
barack94@aol.com,



}}]
  • Two representations of the same data:/contacts @interface Contact : RKObject { NSNumber* _contactID; NSString* _fullName; NSString* _email;[{ }



contact:
{







id:
1234, @property (retain) NSNumber* contactID; @property (retain) NSString* fullName;







full_name:
Peter
Marks, @property (retain) NSString* email;







email:
petertmarks@gmail.com, @end



}}, @implementation Contact @synthesize ...;{



contact:
{ + (NSDictionary*)elementToPropertyMappings {







id:
3456, return [NSDictionary dictionaryWithKeysAndObjects: @"id", @"contactID",







full_name:
Barack
Obama, @"full_name", @"fullName",







email:
barack94@aol.com, @"email", @"email",



} nil];}] } @end
  • Fetch objects from server- (void)applicationDidFinishLaunching:(UIApplication*)application withOptions:(NSDictionary*)options { RKClient* client = [RKClient clientWithBaseURL:@"http://restkit.org"];}- (void)loadContact { RKObjectManager* manager = [RKObjectManager objectManagerWithBaseURL:@"http://restkit.org"]; [manager loadObjectsAtResourcePath:@"/contacts/1" objectClass:[Contact class] delegate:self]}- (void)objectLoader:(RKObjectLoader*)objectLoader didLoadObjects:(NSArray*)objects { Contact* contact = [objects objectAtIndex:0]; NSLog(@"Loaded Contact ID #%@ -> Name: %@, Company: %@", contact.id, contact.name, contact.company);}
  • Set up routes- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { RKDynamicRouter* router = [RKDynamicRouter new]; // Define a default resource path for all unspecified HTTP verbs [router routeClass:[Contact class] toResourcePath:@"/contacts/(contactID)"]; [router routeClass:[Contact class] toResourcePath:@"/contacts" forMethod:RKRequestMethodPOST]; [RKObjectManager sharedManager].router = router;}
  • Post object to server- (void) postObject { Contact * newContact = [[Contact alloc] init]; newContact.fullName = @"Peter Marks"; newContact.email = @"petertmarks@gmail.com"; [[RKObjectManager sharedManager] postObject:newContact delegate:self];}- (void)objectLoader:(RKObjectLoader*)objectLoader didLoadObjects:(NSArray*)objects { Contact* contact = [objects objectAtIndex:0]; NSLog(@"Loaded Contact ID #%@ -> Name: %@, Company: %@", contact.contactID, contact.fullName, contact.company);}
  • Core Data
  • Core Data@interface Contact : RKManagedObject {}@end@implementation Contact@synthesize ...;+ (NSDictionary*)elementToPropertyMappings { return [NSDictionary dictionaryWithKeysAndObjects: @"id", @"contactID", @"full_name", @"fullName", @"email", @"email", nil];}+ (NSString*)primaryKeyProperty { return @"contactID";}@end
  • Relationship modeling[{"project":
{



"id":
123,



"name":
"Produce
RestKit
Sample
Code",



"description":
"We
need
more
sample
code!",



"user":
{







"id":
1,







"name":
"Blake
Watters",







"email":
"blake@twotoasters.com"



},



"tasks":
[







{"id":
1,
"name":
"Identify
samples
to
write",
"assigned_user_id":
1},







{"id":
2,
"name":
"Write
the
code",
"assigned_user_id":
1},







{"id":
3,
"name":
"Push
to
Github",
"assigned_user_id":
1},







{"id":
4,
"name":
"Update
the
mailing
list",
"assigned_user_id":
1}



]}},
  • Relationship mapping
  • Relationship mapping@interface Project : RKManagedObject { NSNumber* _projectID; NSString* _name; NSString* _description; NSString* _userID; User* _user; NSArray* _tasks;}@property (nonatomic, retain) NSNumber* projectID;@property (nonatomic, retain) NSString* name;@property (nonatomic, retain) NSString* description;@property (nonatomic, retain) NSString* userID;@property (nonatomic, retain) User* user;@property (nonatomic, retain) NSArray* tasks;@end
  • Relationship mapping@interface Project : RKManagedObject { NSNumber* _projectID; @implementation Project NSString* _name; @dynamic ...; NSString* _description; NSString* _userID; + (NSDictionary*)elementToPropertyMappings {...} User* _user; NSArray* _tasks; - (NSString*) primaryKeyProperty {} return projectID; }@property (nonatomic, retain) NSNumber* projectID;@property (nonatomic, retain) NSString* name; + (NSDictionary*)elementToRelationshipMappings {@property (nonatomic, retain) NSString* description; return [NSDictionary dictionaryWithKeysAndObjects:@property (nonatomic, retain) NSString* userID; @"user", @"user",@property (nonatomic, retain) User* user; @"tasks", @"tasks",@property (nonatomic, retain) NSArray* tasks; nil]; }@end + (NSDictionary*)relationshipToPrimaryKeyPropertyMappings { return [NSDictionary dictionaryWithObject:@"userID" forKey:@"user"]; } @end
  • Relationship serialization+ (NSArray*)relationshipsToSerialize { return [NSArray arrayWithObject:@"tasks"];}[{"project":
{



"id":
123,



"name":
"Produce
RestKit
Sample
Code",



"description":
"We
need
more
sample
code!",



"tasks":
[







{"id":
1,
"name":
"Identify
samples
to
write",
"assigned_user_id":
1},







{"id":
2,
"name":
"Write
the
code",
"assigned_user_id":
1},







{"id":
3,
"name":
"Push
to
Github",
"assigned_user_id":
1},







{"id":
4,
"name":
"Update
the
mailing
list",
"assigned_user_id":
1}



]}},
  • Object mapping 2.0
  • Object mapping 2.0Everything mentioned is for the current version of 0.9.2
  • Object mapping 2.0Everything mentioned is for the current version of 0.9.2Upcoming version 0.9.3 overhauls of Object mapping
  • Object mapping 2.0Everything mentioned is for the current version of 0.9.2Upcoming version 0.9.3 overhauls of Object mappingMain difference is that mappings are no longer dependenton class inheritance.
  • Object mapping 2.0 Everything mentioned is for the current version of 0.9.2 Upcoming version 0.9.3 overhauls of Object mapping Main difference is that mappings are no longer dependent on class inheritance.// In this use-case Article is a vanilla NSObject with propertiesRKObjectMapping* mapping = [RKObjectMapping mappingForClass:[Article class]];// Add an attribute mapping to the object mapping directlyRKObjectAttributeMapping* titleMapping = [RKObjectAttributeMapping mappingFromKeyPath:@"title" toKeyPath:@"title"];[mapping addAttributeMapping:titleMapping];
  • Other cool stuff
  • RKRequestQueue
  • RKRequestQueue- (void) postObject { Contact * newContact = [[Contact alloc] init]; newContact.fullName = @"Peter Marks"; newContact.email = @"petertmarks@gmail.com"; [[RKObjectManager sharedManager] postObject:newContact delegate:self];}- (void)objectLoader:(RKObjectLoader*)objectLoader didLoadObjects:(NSArray*)objects { Contact* contact = [objects objectAtIndex:0]; NSLog(@"Loaded Contact ID #%@ -> Name: %@, Company: %@",contact.contactID, contact.fullName, contact.company);}
  • RKRequestQueue- (void) postObject { Contact * newContact = [[Contact alloc] init]; newContact.fullName = @"Peter Marks"; newContact.email = @"petertmarks@gmail.com"; [[RKObjectManager sharedManager] postObject:newContact delegate:self];}- (void)objectLoader:(RKObjectLoader*)objectLoader didLoadObjects:(NSArray*)objects { Contact* contact = [objects objectAtIndex:0]; NSLog(@"Loaded Contact ID #%@ -> Name: %@, Company: %@",contact.contactID, contact.fullName, contact.company);}// We have been obscured -- cancel any pending requests- (void)viewWillDisappear:(BOOL)animated { [[RKRequestQueue sharedQueue] cancelRequestsWithDelegate:self];}
  • Background requests- (void)backgroundUpload { RKRequest* request = [[RKClient sharedClient] post:@"somewhere" delegate:self]; request.backgroundPolicy = RKRequestBackgroundPolicyNone; // Take no action with regard to backgrounding request.backgroundPolicy = RKRequestBackgroundPolicyCancel; // If the app switches to the background, cancel the request request.backgroundPolicy = RKRequestBackgroundPolicyContinue; // Continue the request in the background request.backgroundPolicy = RKRequestBackgroundPolicyRequeue; // Cancel the request and place it back on the queue for nextactivation}
  • Multi-part requests// Create an AttachmentRKParamsAttachment* attachment = [params setFile:myFilePath forParam:@"image1"];attachment.MIMEType = @"image/gif";attachment.fileName = @"picture.gif";// Attach an Image from the App BundleUIImage* image = [UIImage imageNamed:@"another_image.png"];NSData* imageData = UIImagePNGRepresentation(image);[params setData:imageData MIMEType:@"image/png" forParam:@"image2"];// Send a Request![[RKClient sharedClient] post:@"/uploadImages" params:params delegate:self];
  • Database seedingRKManagedObjectSeeder* seeder = [RKManagedObjectSeeder objectSeederWithObjectManager: [RKObjectManager sharedManager]];// Seed the database with User objects. The class will be inferred via element registration[seeder seedObjectsFromFiles:@"users.json", nil];
  • Integration LayersRuby on RailsRKRailsRouter – A Router implementation aware of Ruby on Rails idiomsThree20RKRequestTTModel – An implementation of the TTModel protocol forThree20 that allows RestKit object loaders to drive Three20 tables
  • More information• http://Restkit.org• http://github.com/twotoasters/RestKit/• http://groups.google.com/group/restkit
  • Canned discussion prompt:How do others solve this problem?