Developing RESTful iOS Apps with RestKit

Developing RESTful iOS Apps with RestKit

Tutorial Details
  • Technology: iOS SDK
  • Difficulty: Intermediate
  • Estimated Completion Time: 1 - 2 Hours
This entry is part 1 of 2 in the series Developing RESTful iOS Apps with RestKit

RestKit is a powerful library that simplifies interacting with web services for iOS applications. In this article, written by RestKit creator and Two Toasters CTO Blake Watters, we will take a quick tour of RestKit’s feature set, get familiar with the core concepts presented by the library, and then explore some code samples to get a feel for what working with RestKit is really like.

What is RestKit?

RestKit is an Objective-C framework for iOS that aims to make interacting with RESTful web services simple, fast, and fun. It combines a clean, simple HTTP request/response API with a powerful object mapping system that reduces the amount of code you need to write to ‘get stuff done’. RestKit’s primary goal is to allow the developer to think more in terms of their application’s data model and worry less about the details of sending requests, parsing responses, and building representations of remote resources.

What does RestKit provide?

  • A simple, high-level HTTP request/response system. RestKit ships with an HTTP client built on top of NSURLConnection and provides a library of helpful methods for inspecting MIME types and status codes. Submitting form data is as simple as providing a dictionary of parameters and a native params object is included for easily creating multi-part submissions. Simple support for the streaming upload of large files (i.e. videos) is also provided.
  • Framework level support for switching servers & environments (e.g. development, production, staging). RestKit uses a base URL and resource paths rather than full URL’s to allow you to switch target servers quickly. Interpolating URL strings and constructing NSURL objects is a thing of the past.
  • An object mapping system. RestKit provides a modeling layer for mapping processed data payloads into native Cocoa objects declaratively. This lets the application programmer stop worrying about parsing and simply ask the framework to asynchronously fetch a remote resource and call the delegate with the results. Object mapping is implemented using key-value coding, allowing for quick traversal of the parsed object graph. Reflection is used on the property types to allow for mapping from values that don’t have direct representations in the encoding format, such as mapping JSON timestamps encoded as a string to NSDate objects.
  • Core Data support. Building on top of the object mapping layer, RestKit provides integration with Apple’s Core Data framework. This support allows RestKit to persist remotely loaded objects directly back into a local store, either as a fast local cache or a primary data store that is periodically synced with the cloud. RestKit can populate Core Data associations for you, allowing natural property based traversal of your data model. It also provides a nice API on top of the Core Data primitives that simplifies configuration and querying use cases.
  • Database seeding. When the Core Data object store is used, you can seed a database from a collection of data files. This lets you submit your apps to the App Store with a database in the app bundle that is ready for immediate use.
  • Pluggable parsing layer. RestKit currently supports JSON via the SBJSON and YAJL parsers. Parsing is implemented behind a simple interface to allow additional data formats to be handled transparently.
  • Rails integration. RestKit was originally designed as an Objective-C answer to Active Resource. Rails has been used as the backend for a number of RestKit powered iOS apps and turn-key support is provided for interacting with a backend Rails application.
  • Experimental Three20 integration. RestKit is often used alongside the Three20 framework. An optional module is included in the distribution that allows RestKit to interface with Three20 via the TTModel protocol.

Getting Up and Running

RestKit is available as a downloadable binary package, as a versioned snapshot, or as a Git submodule if you wish to track mainline development. For users of the library uninterested in doing development, we recommend using the versioned binary packages for the simplicity of installation. If you wish to install as a submodule or build the library yourself, please refer to the documentation available on Github.

You can install RestKit in a few easy steps:

  1. Head to restkit.org and download the latest version (v0.9.0 as of this writing).
  2. Unpack the archive wherever you like to keep libraries (the author recommends a Library subdirectory).
  3. Drag the RestKit.xcodeproj file to your Xcode project file. It will be added to the Groups & Files section in the left pane of the project. Select the appropriate targets and click ‘Add’ when the sheet appears.
  4. Click on the entry for RestKit.xcodeproj in your project’s Groups & Files section. In the right hand pane, find the entries for libRestKitSupport.a, libRestKitObjectMapping.a, libRestKitNetwork.a, and libRestKitJSONParserYAJL.a and click the checkboxes on the far right underneath the silver target icon. This will link your project against RestKit. If you wish to use the Core Data support, click the checkbox next to libRestKitCoreData.a also. Your project should appear something like the following screenshot:
  5. Find the target for your application in the Targets section of your project. Right click on your app’s target and select ‘Get Info’ from the menu to open the target Info inspector window.
  6. You should be looking at the General tab of your target’s inspector. In the top Direct Dependencies section, click the plus button and add a direct dependency on the RestKit target.
  7. Now look to the bottom of the General pane labeled Linked Libraries. Click the plus button to open the Frameworks selection sheet. Find and select the following frameworks and click ‘Add’:
    1. CFNetwork.framework – Required for networking support.
    2. SystemConfiguration.framework – Required for detection of network availability.
    3. MobileCoreServices.framework – Required. Provides support for MIME type auto-detection for uploaded files.
    4. CoreData.framework – Required. Required for use of the Core Data backed persistent object store.
  8. Switch to the ‘Build’ tab in your project inspector. Make sure that your Configuration pop-up menu reads All Configurations so that your changes will work for all build configurations.
  9. Find the Header Search Paths setting. Double click and add a new entry. When RestKit is compiled, it will copy all relevant headers to the appropriate location under the /Build directory within the RestKit checkout. You need to add a path to the /Build directory of RestKit, relative to your project file. For example, if you checked the submodule out to the ‘Libraries’ subdirectory of your project, your header path would be ‘Libraries/RestKit/Build’.

    Now find the Other Linker Flags setting. Double click it and add entries for -all_load and -ObjC. Your setting should match the screenshot below.

  10. Close out the inspector window.

Congratulations, you are now done adding RestKit into your project!

You now only need to add includes for the RestKit libraries at the appropriate places in your application. The relevant includes are:

    #import <RestKit/RestKit.h>
    #import <RestKit/CoreData/CoreData.h>// If you are using Core Data…

Build the project to ensure everything is working correctly.

Once you have verified that you have RestKit linked into your project correctly, you are ready to begin using the library.

Using RestKit

RestKit is designed to make common tasks as straightforward and simple as possible. In this section we will run through many common tasks in the library and focus on code samples to help you get started with the library.

Sending requests & processing responses

All of RestKit’s higher level functionality is built on top of the network layer. The network layer’s primary responsibility is the construction and dispatch of requests and the processing of responses. Generally you will dispatch all requests through the RKClient class.

RKClient is a web client object configured to talk to a particular web server. It is initialized with a base URL and allows you to set configuration that is common to the requests in your application, such as HTTP headers and authentication information. While you are free to initialize as many instances of RKClient as is appropriate for your application, there is a shared singleton instance that is globally available. This singleton instance is often configured in your app delegate’s applicationDidFinishLaunching:withOptions: method:

- (void)applicationDidFinishLaunching:(UIApplication*)application withOptions:(NSDictionary*)options {
    RKClient* client = [RKClient clientWithBaseURL:@"http://restkit.org"];
}

The first RKClient that is initialized is automatically configured as the singleton instance and becomes available via the sharedClient singleton method:

NSLog(@"I am your RKClient singleton : %@", [RKClient sharedClient]);

Now that you have a client configured, you can send and process HTTP requests through the client. RestKit makes this very easy for you and abstracts the low level details of NSURLConnection away from you. When making a request through the client, you supply the resource path on the remote web server that you wish to interact with. Since the most common action in an iOS application is making an asynchronous request to a remote web service, RestKit provides very straight-forward convenience methods for the HTTP verbs: GET, POST, PUT and DELETE. You only need to declare that your class implements the RKRequestDelegate protocol and then provide an implementation of the request:didLoadResponse: method. Let’s take a look at an example class that shows the basics:

#import <RestKit/RestKit.h>
// Here we declare that we implement the RKRequestDelegate protocol
// Check out RestKit/Network/RKRequest.h for additional delegate methods
// that are available.
@interface RKRequestExamples : NSObject <RKRequestDelegate> {
}
@end
@implementation RKRequestExamples
- (void)sendRequests {
  // Perform a simple HTTP GET and call me back with the results
  [[RKClient sharedClient] get:@"/foo.xml" delegate:self];
  // Send a POST to a remote resource. The dictionary will be transparently
  // converted into a URL encoded representation and sent along as the request body
  NSDictionary* params = [NSDictionary dictionaryWithObject:@"RestKit" forKey:@"Sender"];
  [[RKClient sharedClient] post:@"/other.json" params:params delegate:self];
  // DELETE a remote resource from the server
  [[RKClient client] delete:@"/missing_resource.txt" delegate:self];
}
- (void)request:(RKRequest*)request didLoadResponse:(RKResponse*)response {
  if ([request isGET]) {
    // Handling GET /foo.xml
    if ([response isOK]) {
      // Success! Let's take a look at the data
      NSLog(@"Retrieved XML: %@", [response bodyAsString]);
    }
  } else if ([request isPOST]) {
    // Handling POST /other.json
    if ([response isJSON]) {
      NSLog(@"Got a JSON response back from our POST!");
    }
  } else if ([request isDELETE]) {
    // Handling DELETE /missing_resource.txt
    if ([response isNotFound]) {
      NSLog(@"The resource path '%@' was not found.", [request resourcePath]);
    }
  }
}
@end

As you can see, the code is extremely succinct and readable. There are a number of helper methods available on RKRequest and RKResponse that make inspecting your request state very easy. Be sure to read the headers and get familiar with what’s available.

An Introduction to Object Mapping

Sending and receiving HTTP requests with such ease is great and all, but that’s just the tip of the iceberg. RestKit’s real power comes not from the network layer, but from the object mapping layer that sits on top of it. Object mapping is RestKit’s solution to simplifying and DRYing up the overly verbose work-flow of:

  1. Sending a request to a remote web service.
  2. Getting back an XML or JSON response and parsing it.
  3. Taking the parsed response and assigning the values inside the payload to objects.

Much as RKClient is your gateway to a simpler life with HTTP, RKObjectManager is your gateway to the world of object mapping. In fact, on projects where object mapping is used extensively you will initialize RKObjectManager instead of RKClient. Much as RKClient seeks to abstract away the gritty details of handling requests, RKObjectManager works hard to shield you from the complexities of transforming data payloads into objects.

Modeling & Loading Remote Objects

Object mapping requires that you provide a data model class to represent your remote objects. By implementing the RKObjectMappable protocol, you are configuring RestKit to map attributes within a retrieved payload to properties on your model class. The key to this process is the elementToPropertyMappings method, which defines a dictionary of key paths and property names. The key paths are key-value coding compliant strings for accessing data within a parsed document. The property name is simply the string name of a property on the class to assign the accessed data to.

To illustrate these points, let’s imagine that our application has a lightweight contact concept containing a name, an e-mail address, and an identifier number. Let’s imagine that this record lives on our remote server at /contacts/1234. The JSON looks like this:

{'id': 1234,
 'name': 'Blake Watters',
 'company': 'Two Toasters'}

Let’s pull together an RKObject class to contain this data:

@interface Contact : RKObject {
  NSNumber* _identifier;
  NSString* _name;
  NSString* _company;
}
@property (nonatomic, retain) NSNumber* identifier;
@property (nonatomic, retain) NSString* name;
@property (nonatomic, retain) NSString* company;
@end

Now we just need to tell RestKit how to map data from the payload to our properties:

@implementation Contact
- (NSDictionary*)elementToPropertyMappings {
  return [NSDictionary dictionaryWithKeysAndObjects:
          @"id", @"identifier",
          @"name", @"name",
          @"company", @"company",
          nil];
}
@end

We are now all set to load the data. To do this, we set up RKObjectManager and execute a GET on the record. RKObjectManager will construct and configure an asynchronous RKObjectLoader request for you and send it to the remote server for processing. Instead of implementing the low level RKRequestDelegate methods that deal with requests and responses, we will instead implement the RKObjectLoaderDelegate protocol and get called back with a collection of mapped objects or an error. Let’s take a look at this code:

- (void)loadContact {
  RKObjectManager* manager = [RKObjectManager objectManagerWithBaseURL:@"http://restkit.org"];
  [manager loadObjectsAtResourcePath:@"/contacts/1" objectClass:[Contact class] delegate:self]
}
// RKObjectLoaderDelegate methods
- (void)objectLoader:(RKObjectLoader*)objectLoader didLoadObjects:(NSArray*)objects {
  Contact* contact = [objects objectAtIndex:0];
  NSLog(@"Loaded Contact ID #%@ -> Name: %@, Company: %@", contact.id, contact.name, contact.company);
}
- (void)objectLoader:(RKObjectLoader*)objectLoader didFailWithError:(NSError*)error {
  NSLog(@"Encountered an error: %@", error);
}

As you can see, the entire process is very low ceremony and completely DRY.

Setting Up Routes

Loading objects is only half the story. To really interact with a remote web service, you also need to be able to create, update, and delete remote object instances. A confounding factor in these interactions is often that the resource path that an object resides at is specific to each instance. Returning to the contacts example above, imagine that the entire world of Contacts is represented by the following pairs of HTTP verbs and resource paths:

  • GET /contacts returns all Contacts as a collection
  • POST /contacts creates a new Contact
  • GET /contacts/<id> returns a particular Contact details
  • PUT /contacts/<id> updates an existing Contact details
  • DELETE /contacts/<id> deletes an existing Contact

To avoid littering code with these conventions and resource paths, RestKit offers a routing system that is capable of generating resource paths for an object. Routing is designed to be an extensible system to provide flexibility, but RestKit ships with a very capable implementation in the RKDynamicRouter class. Routing is enabled by assigning an instance of an object implementing the RKRouter protocol to the RKObjectManager and configuring the router appropriately. Let’s take a look at an example configuration using RKDynamicRouter and our Contact example:

RKDynamicRouter* router = [RKDynamicRouter new];
// Define a default resource path for all unspecified HTTP verbs
[router routeClass:[Contact class] toResourcePath:@"/contacts/(identifier)"];
[router routeClass:[Contact class] toResourcePath:@"/contacts" forMethod:RKRequestMethodPOST];
[RKObjectManager sharedManager].router = router;

The notable piece in the configuration is the use of parentheses in the resource path for the default route. Within the parentheses you can specify any instance method on the class being configured and when RestKit generates a resource path for that object, the value returned will be interpolated into the string.

In our example above, we can see that GET, PUT, and DELETE operations will generate /contacts/1234 while POST will generate /contacts.

Manipulating Remote Objects

Now that we have configured routing, we can manipulate remote object representations at a very high level. Let’s take a look at some more code and then we’ll walk through the process:

- (void)createObject {
  Contact* joeBlow = [Contact object];
  joeBlow.name = @"Joe Blow";
  joeBlow.company = @"Two Toasters";
  // POST to /contacts
  [[RKObjectManager sharedManager] postObject:joeBlow delegate:self];
}
- (void)updateObject {
  Contact* blake = [Contact object];
  blake.identifier = [NSNumber numberWithInt:1];
  blake.name = @"Blake Watters";
  blake.company = @"RestKit";
  // PUT to /contacts/1
  [[RKObjectManager sharedManager] putObject:blake delegate:self];
}
- (void)deleteObject {
  Contact* blake = [Contact object];
  blake.identififer = [NSNumber numberWithInt:1];
  // DELETE to /contacts/1
  [[RKObjectManager sharedManager] deleteObject:blake delegate:self];
}

What we have done here is used the combined power of object mapping and routing to perform very high level manipulations on local and remote objects. Behind the scenes, RestKit has identified the appropriate resource path for your operation, created and dispatched an asynchronous request, and processed the response for you.

Review of Key Concepts

  • Client and Object Manager. There are two primary entry points for working with RestKit in your application: RKClient and RKObjectManager. RKClient is the primary entry point when you are working with the Network layer of RestKit and concerns itself with the low level details of building and sending requests. RKObjectManager operates at a higher level of abstraction in the Object Mapping layer and concerns itself with the loading and manipulation of objects that represent remote resources. Depending on what you are trying to accomplish with RestKit, you will be working extensively with one (or both!) of these classes.

  • Base URL’s and Resource Paths. RestKit uses the concepts of the ‘Base URL’ and ‘Resource Path’ to coordinate access to remote object representations. The Base URL is simply the common part of all URL’s to your remote application and is used to initialize instances of the RKClient and RKObjectManager classes. A resource path is simply the path (or subpath) portion of the full URL to an HTTP resource. Given an RKClient object initialized with ‘http://restkit.org’ and a request to GET the content at resource path ‘/foo/bar.json’, RestKit will create and send a request to ‘http://restkit.org/foo/bar.json’. This allows you to easily support development, staging, and production environments in your applications by conditionally compiling different base URL’s. Most of the time you will think entirely in terms of resource paths once you have moved beyond initializing the library.

Example:

RKClient* client = [RKClient clientWithBaseURL:@"http:///restkit.org"];
[client get:@"/foo/bar.json" delegate:self];
  • Object Mapping. When you use RestKit to model remote resources into local objects, you will be interacting with the object mapping layer. Object mapping is the process of taking a remote JSON (or other wire format) payload, parsing it into a graph of key value coding compliant NSObject’s, and applying a set of mapping rules to transform values inside the parsed object graph into attributes on a model object. RestKit supports advanced mapping beyond what you get from simply decoding a payload, such as parsing a string containing a date into an NSDate property and accessing data via key-value coding operators. Object mapping rules are configured by implementing the elementToPropertyMappings method of the RKObjectMappable protocol:

Example:

@implementation MyObject
// Map full_name and street_adddress in JSON payload to
// local properties fullName and streetAddress
+ (NSDictionary*)elementToPropertyMappings {
    return [NSDictionary dictionaryWithKeysAndObjects:
            @"full_name", @"fullName",
            @"street_address", @"streetAddress",
            nil];
}
@end
  • Routing. The routing system is responsible for generating resource paths from local object instances. This allows you to manipulate and synchronize your local objects with their remote representations without ever seeing a URL. The routing system is extensible by providing your own implementation of the RKRouter protocol, but RestKit ships with a powerful implementation in the RKDynamicRouter class. The dynamic router allows you to encoded property names inside of simple strings to generate complex resource paths at run time. This is most easily understood through some examples:

Example:

RKObjectManager* manager = [RKObjectManager objectManagerWithBaseURL:@"http://restkit.org"];
RKDynamicRouter* router = [[RKDynamicRouter new] autorelease];
manager.router = router;
// Send POST requests for instances of Article to '/articles'
[router routeClass:[Article class] toResourcePath:@"/articles" forMethod:RKRequestMethodPOST];
// Configure a default resource path for Articles. Will send GET, PUT, and DELETE requests to '/articles/XXXX'
// articleID is a property on the Article class
[router routeClass:[Article class] toResourcePath:@"/articles/(articleID)"];
// Configure Comments on the Article. Send POST of Comment objects to '/articles/1234/comments'
// where the Comment has a relationship to an Article.
[router routeClass:[Comment class] toResourcePath:@"/articles/(article.articleID)/comments" forMethod:RKRequestMethodPOST];
// Let's create an Article
Article* article = [Article object];
article.title = @"Foo";
article.body = @"This is the body";
// Send a POST to /articles to create the remote instance
[[RKObjectManager sharedManager] postObject:article delegate:self];
// Now let's create a Comment on the Article
Comment* comment = [Comment object];
comment.article = article;
comment.body = @"This is the comment!";
// Given Article has an ID of 1234, will send a POST to /articles/1234/comments to create the Comment
[[RKObjectManager sharedManager] postObject:comment delegate:self];
// Delete the Article. DELETE to /articles/1234
[[RKObjectManager sharedManager] deleteObject:comment delegate:self];

Conclusion

This article has explored the basics of working with RestKit. You should now have a firm understanding of the core concepts and feel well prepared to start building your next RESTful iOS app. As we mentioned in the introductory section, RestKit also includes some advanced features which were not explored in this article. We will fully explore the advanced portions of the library including Core Data in our upcoming advanced tutorial. Until then, you can learn more through the example code included with the library and by exploring the resources below.

Learning More

Series NavigationiOS SDK: Advanced RestKit Development»

Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • http://www.lamiscela.net Junio Vitorino

    Hi congratulations by the article, it’s helping me a lot in a new project. I’d like only notify of that the article talks to use the Header Search Paths setting but the image bellow sets one other setting the Framework Search Paths.

  • http://tudormunteanu.com/ Tudor Munteanu

    Can RestKit replace ASIHTTPRequest or are they compementary?

    • http://twotoasters.com/ Blake Watters
      Author

      Hi Tudor -

      RestKit implements most of the functionality found in ASIHTTPRequest. There are some features that ASI supports that RestKit does not have analogous functionality for, but the object mapping system in RestKit is the core feature-set that ASI does not address at all. ASIHTTPRequest is lower level, more complete HTTP swiss-army knife. RestKit is a high level object modeling framework with a leaner, but still highly functional set of HTTP capabilities. In the end you’ll need to pick what’s right for your project.

      Best,
      Blake

  • http://www.appjon.com AppJon

    Wow, this is a beautiful guide. Thanks for taking the time to put this together!

  • http://doronkatz.com Doron Katz

    Do you have an xCode 4 tutorial for this because i cant seem to especially get xcode 4 setup with restkit

  • moosc

    Congrats for the article.
    But for another tutorial, please, post the full source code. It’s more easier download the source code and begin ti play.

    • http://restkit.org Blake Watters
      Author

      Definitely will do in the advanced tutorial!

  • Jooi

    I got this error message after I set everything according to the above instruction.
    error: RestKit/RestKit.h: No such file or directory

    • http://restkit.org/ Blake Watters
      Author

      Hi Jooi -

      Are you running on Xcode 4.0 by any chance? Because of changes to default project build environments introduced in Xcode 4.0, the library needed some updates. I just pushed them last night. If you pull the latest code form Github you should be in good shape.

      Best,
      Blake

      • maxime

        I’m using xCode 3.2.4 and I have the same problem. Checked all the manipulations twice, what’s wrong ?

      • PK

        Total noob, still struggling with this error:
        RestKit/RestKit.h: No such file or directory

        I know it is an error on my part with:
        “the author recommends a Library subdirectory” in step #2

        Can someone please provide a specific example of both:

        1) path to directory in step #2
        2) path used for “Header Search Paths” in step #9

        I understand that this could be personal preference, but as I have no experience, I need something more solid than “a Library directory.”

        Thanks in advance, can’t wait to use RestKit.

  • David

    Need help clarifying a ‘basic’ point of usage…

    I have successfully connected my iPhone app to a PHP script that returns JSON using a path of //localhost/contacts.php.

    I am now trying to implement the practice of routing (very cool btw), but am confused by the (above) example:

    [router routeClass:[Article class] toResourcePath:@”/articles” forMethod:RKRequestMethodPOST];

    Specifically the value of toResourcePath being set to “/articles”…Why is there no file extension? I was expecting “.php” as previously. Is this due to the Rails integration? (No experience with Rails here). Can I implement Routing without Rails?

    • http://restkit.org/ Blake Watters
      Author

      Hi David -

      The resource path is completely arbitrary. Rails (and many other web frameworks) do not use source code stored underneath the document root of the web server — they instead specifically expose certain URL endpoints for processing. If you are talking to a PHP server, your resource path may well be article.php?action=create or something. There is nothing specific to Rails.

      Best,
      Blake

  • Eric Newman

    This is almost great. I’m not having much luck with actual code. I have everything running with no errors, but it doesn’t work. A few questions;

    1) Why the variables with the underscores in the object declaration?
    You don’t show the rest of the code, so I’m no sure what mechanism maps these to the real local variables.
    2) The delegates aren’t shown anywhere. Not sure who’s delegating what, or where this is best fit into a real application.
    3) Source Code!!!!! Can we please see the rest of this.
    4) Is a model file needed? I see no mention of a .xcdatamodel file…

    My basic problem is the array of objects returned by “didLoadObjects” is always empty. No errors thrown.

    I’m returning a single unnamed dictionary, similar to the example above so I’m not using a mapper…

    Any ideas?

    • http://restkit.org/ Blake Watters
      Author

      Hi Eric -

      Thank you for the feedback. I am in the process or writing the advanced section and will provide full source code to go along with the examples in the next article.

      Now for your questions:
      1) The underscores are used to denote instance variables instead of local variables. It’s only a style point with the way I write Objective-C code. They are mapped to properties via @synthesize foo = _foo;
      2) If you pull the latest sources from Github and look in the Examples/ subdirectory, we have provided a full-featured sample application that shows how to work with the entire framework. The server portion is included as well.
      3) Will do.
      4) When you are working with non-Core Data backed models, there is no .xcdatamodel file necessary. I am covering Core Data extensively in the advanced tutorial.

      You may want to try returning your dictionary wrapped into an array. I have had a recent bug report that single objects returned for a load are not mapping. I will be fixing it ASAP.

      If you have any more problems, don’t hesitate to reach out to me directly: blake@twotoasters.com

      Best,
      Blake

    • http://www.whosebill.com Paul Moore

      Eric

      I had similar symptoms when migrating from standalone objects to Core Data. Essentially, I changed my objects to extend RKManagedObject but hadn’t understood that the definition of the properties needed to change to meet the requirements of Core Data.

      Once I had removed the declarations from the @interface in the header file, and changed from @synthesize to @dynamic in the implementation, things have been a lot smoother.

      If you’re using the debugger you can use “po [ objectID]” which will show you if you’re actually getting a Core Data object back. The ‘lack of properties’ for a Core Data object suggests you’re suffering the problem as above

      Hope that helps

      Paul

  • Ravi Shankar

    I am using Xcode 3.2.4 version, I followed all the steps given in this tutorial and have downloaded latest V0.9 version of restkit from http://restkit.org/, but still getting “RestKit/RestKit.h: No such file or directory” can you please help me out in resolving this issue.

    Regards.

    • http://restkit.org/ Blake Watters
      Author

      Hi Ravi -

      You may want to try grabbing a new snapshot from Github. I have been fighting through issues introduced with the release of Xcode 4 and now have install instructions for Xcode 3 and 4 up on the Github site.

      Best,
      Blake

  • Mads Kleemann

    Great tutorial!
    When can we expect the advanced one? with core data :)

    • http://restkit.org/ Blake Watters
      Author

      Hi Mads -

      I am nearly finished with the first draft of the article. I am currently working through the Core Data section, which is the longest and most involved portion of the article. I expect to have it out to my reviewers this week and the final draft submitted shortly thereafter. Once we get there I’ll be able to get clarity from MobileTuts around publication.

      I’ll definitely keep everyone in the comments updated!

      Best,
      Blake

      • Mads Kleemann

        Thanks for the respons.
        Great, i’m really looking forward to it ;)
        Keep up the good work

  • Jeff

    Im not sure if this has been cleared up or not yet, but I had the same issues with compiler errors saying that the header files could not be found. I am embarrassed to admit that it was a combination of lack of attention to detail and reading on my part.

    I’m a visual person and like to look at the screen shots to go off of and only glanced at the text (dangerous in many circumstances I know).

    Well, in step 9 your instructions state to “Find the Header Search Paths” setting but the screen shot has the value being placed in the “Framework Search Paths” setting.

    When I followed the picture, it did not work. However, when I followed the written directions, it worked fine…so far ;-)

    Hope this simple fix helps. Great lesson in being more careful RTFM’ing.

    Thanks for all your work…keep it up.

  • http://blog.4minds.com Brian Richmond

    I’m thinking about switching my current REST wrapper out with RestKit since it looks to be more robust and easier to use than what I have currently. I’m struggling now with image uploads. My back-end API is all PHP, and just uses the multipart form data to grab the image and save it. I found that I had to manually build out the entire form on the iOS end to simulate a HTML form, and it just seems rather clunky, not to mention that I had to modify code that I really shouldn’t have had to.

    At any rate, it’s working most of the time, however I keep getting out of memory errors on the iOS device when attempting to upload, primary when I’m not on Wifi. How does RestKit perform its image uploads? Do you have any examples of this?

  • vinny

    Does RESTKit support requests sent to a web service secured by OAuth ?

  • Kunal

    Great work done ! just downloaded the latest version, installed ruby and ruby gems. Tried the examples with database. Works smooth.

  • Dru Kepple

    Just a question…I see in your RKObject subclass examples, you have [NSDictionary dictionaryWithKeysAndObjects:...];

    dictionaryWithKeysAndObjects? Should that be dictionaryWithObjectsAndKeys? Or am I missing something?

    Also, is that .m file complete? Should there be some @synthesize statements?

    I’m not a particularly talented iOS developer, so maybe I’m just missing something, but I’m getting errors if I try to put in the code as presented.

  • Bjorn

    Very nice article! I know you got samples in the project but this one in the article seems less complicated. Can’t you make the source code for this example in the article available so we can download it? Its easer to follow the steps in this article if you have the source code to follow. Or if you want to mail it to me on bjorn.steneram@gmail.com. Again thanks for a great article!

  • Linda

    Nice article! :-)

    Ok, I found my iOS kit for doing RESTful work on client side, even though I miss OAuth. But support for that may be coming?

    Now I want to find a lean framework on server-side in PHP. It must be true RESTful, use MySQL for storage and OAuth (preferably v2) for security. No need for fancy UI-widgets… Is there such a lean and mean framework for PHP? If not, what else do you recommend?

    Thanks in advance, and keep up the good work of yours Blake!

    Regards,
    Linda

  • Andras Hatvani

    This is a very nice and quite complete beginner’s guide sufficient for understanding the basic concepts of RestKit.
    One thing I was wondering about is [NSDictionary dictionaryWithKeysAndObjects:]: I simply do not have this method, in my NSDictionary class, but only [NSDictionary dictionaryWithObjectsAndKeys:]. Even the reference of NSDictionary only mentions latter method – so where does your version come from?

  • Kurt T

    Blake,

    I would love to have some very basic samples, based on a Ruby on Rails app generated with the scaffold command. It would really help a relative noob to see the whole picture with all of the simple code (objective-C and Ruby on Rails). Hope you can find a spare minute some day.

    Thanks,

    Kurt

    • Isla

      I would join Kurt in this request. Many thanks in advance!

  • David J

    This looks very useful. How do you tell it to use XML with RKObjectManager? It seems to default to JSON.

  • Carl Grainger

    Awesome work as ever but this is especially relevant for me – I can’t wait for the advanced follow-up with core-data. Do you have a release date for part 2?

  • http://pulkitsinghal.blogspot.com Pulkit Singhal

    In the code above for “Modeling & Loading Remote Objects” section … elementToPropertyMappings is defined as an instance method for Contact implementation class … is that a typo/mistake or is it intentional? Notice the use of “-” instead of the “+” symbol…

  • chris

    Fantastic, exactly what i was looking for. Thanks.

  • Marco

    Hi, I tried the tutorial step by step with xcode 3.2 and get this build error:

    Command /Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/gcc-4.2 failed with exit code 1

    Any clues for me?

    Thank you,

    Marco

  • Mike

    Can you show an example of using the default object mapping with a GET request?

    You set up a default for articles/articleid

    [router routeClass:[Article class] toResourcePath:@”/articles/(articleID)”];

    so how would I use it, the POST examples are posting an instance of article, but in the get function, I wouldn’t correct?

    Which method of RKObjectManager would I use to load it, the only ones I see require an GET object.

  • Matt Richards

    In the modelling section you reference RKObject.

    I can’t find RKObject anywhere, or mentioned anywhere other than above?

    Am I missing something?

    Thanks in advance.

  • http://www.sina.com.cn/ xixihaha567

    I observe youve not composed 1 much more blog website for a time?

  • David

    THANK YOU for this detailed documentation, it worked the first time. Totally fantastic!

  • Kasper

    Any chance that this excellent guide will be updated to ObjectMapping 2.0?

  • Rebecca

    This tutorial really needs to be updated to the latest version of RestKit.

  • Salil

    I have followed all instructions for Xcode 4 from https://github.com/RestKit/RestKit/wiki/Installing-RestKit-in-Xcode-4.x. I have the #import Fails problem so I followed the solution given
    here – https://github.com/RestKit/RestKit/wiki/Installation-Troubleshooting

    After doing everything I still cannot import the restkit.h file.

    Anything that I might be missing ?

  • Jake

    Whats the reason you didn’t use something like the Drupal iOS SDK, or try to contribute to it?

  • Mike Jones

    Blake,

    I’m double trouble – an iOS/Objective C newbie and am using XCode 4.2, which doesn’t line up precisely to your howto screenshots. Sorry for being so helpless, but do you know of a howto that shows how to link RestKit in 4.2? I’ve made it pretty far by myself, but I’m stuck. I created a workspace, shoved my sample app and RestKit inside it, hooked up the library linking and user defined headers, etc. That got me past a bazillion compiler errors, but I’m stuck on compiler errors in RestKit itself, e.g.:

    RKObjectLoader.h: can’t find protocol declaration for RKRequestDelegate
    (and some others, shortened for brevity)
    RKObjectManager.h: unknown type name RKClient
    (and some others)
    RKObjectRouter.h: expected a type for RKRequestMethod
    (and some others)
    RKLog.h: lcl.h file not found

    I figure I’m still missing some config options, but I don’t know what they might be. Suggestions for how to get this to compile? Thanks.

  • John Green

    The line:

    [manager loadObjectsAtResourcePath:@"/contacts/1" objectClass:[Contact class] delegate:self]

    doesn’t compile anymore, objectClass isn’t part of the signature. I tried taking it out (and adding in the objectMapping tag) but I’m still getting a crash.

  • Guilherme Trein

    First of all, awesome work!

    But I’m facing a problem trying to send request more than once. As in your tutorial, I used the method

    [[RKClient sharedClient] get:@”/foo.xml” delegate:self];

    but it seems that the request is sent just once even if my action (triggered by a button in UIViewController) is executed several times.

    Am I doing something wrong. Thanks in advance!

    • sridhar pathina

      Hi,

      I am trying to upload a video to webserver. I have used the same code that shows in RKParamsExample in RKCatalog. When I try to upload a video it says “Upload successfull”. But I don’t see my video on the server. Please tell me where I am doing wrong. Thanks for your help.

      Sridhar

  • KY

    This is a great article for me to learn the concept of route! One question I have though is how to specify userData (of RKObjectLoader instance) when I call postObject/putObject/deleteObject and so on?

    Keep up the good work!

  • http://www.google.com Brian J.

    Thank you so much for this – im starting to learn how REST is working and is already finish making the server. So this is great but im having some issues for doing the examples.

    Is it possible to get the example of https://github.com/RestKit/RestKit/wiki/Installing-RestKit-in-Xcode-4.x ? I especially like the simple structure of POST, GET etc.

  • Hikmat Khan

    First of all awesome work buddy

    This tutorial really needs to be updated to the latest version of RestKit which provide support for web services secured by Oauth..

  • http://qbc.com Dan

    Can somehow design a schematic that do-away with the manual mapping and assign ‘xml’ or ‘json’ names to class variables all-together? Am I offering a suggestion, asking for a feature request or hoping for something really useful…. hmmmm.

  • http://localhost Adrienne

    Hi,

    I must write this:

    RKDynamicRouter* router = [RKDynamicRouter new];
    manager.router = router;

    because I use RestKit and RKDynamicRouter doesn’t exists…

    Thank you very much
    I see you have post your mail address, can I ask you and show you my problem please?

  • Jim

    Sorry but it simply does NOT work. The how-to stop matching xcode where is says: “find the entries for libRestKitSupport.a, libRestKitObjectMapping.a, libRestKitNetwork.a, and libRestKitJSONParserYAJL.a and click the checkboxes on the far right underneath the silver target icon”.

    There are no such lib’s or place to click on them. Maybe this is for an old version of xcode or the RestKit zip has changed. In either case if I knew which I would not need a how-to.

    Thanks

  • Vinh
  • http://www.facebook.com/domingokyle Kyeru Emmanueru

    How to use this for development in iOS ? :O

  • Tim

    I think that elementToPropertyMappings may no longer be needed as it is not written in some other tutorial site: http://www.raywenderlich.com/13097/intro-to-restkit-tutorial
    Also inheritance to RKObject was not used there.

  • Ram Kri

    can you please suggest rest kit integration for ios 6 iam getting erors