First cut at new README.md file for 0.20.x

This commit is contained in:
Blake Watters
2012-09-02 11:42:20 -04:00
parent 9c9126c6ce
commit d25a5ee308

559
README.md
View File

@@ -1,122 +1,497 @@
Introduction
=========================
# RestKit
RestKit is a Cocoa framework for interacting with RESTful web services in Objective C on iOS and Mac OS X. It provides a set of primitives for interacting with web services wrapping GET, POST, PUT and DELETE HTTP verbs behind a clean, simple interface. RestKit also provides a system for modeling remote resources by mapping them from JSON (or XML) payloads back into local domain objects. Object mapping functions with normal NSObject derived classes with properties. There is also an object mapping implementation included that provides a Core Data backed store for persisting objects loaded from the web.
RestKit is a modern Objective-C framework for implementing RESTful web services clients on iOS and Mac OS X. It provides a powerful [object mapping]() engine that seamlessly integrates with [Core Data](http://developer.apple.com/library/mac/#documentation/cocoa/Conceptual/CoreData/cdProgrammingGuide.html) and a simple set of networking primitives for mapping HTTP requests and responses built on top of [AFNetworking](https://github.com/AFNetworking/AFNetworking). It has an elegant, carefully designed set of APIs that make accessing and modeling RESTful resources feel almost magical. For example, here's how to access the Twitter public timeline and turn the JSON contents into an array of Tweet objects:
RestKit was first publicly introduced in April of 2010.
``` objective-c
@interface Tweet : NSObject
@property (nonatomic, copy) NSNumber *userID;
@property (nonatomic, copy) NSString *username;
@property (nonatomic, copy) NSString *text;
@end
To get started with installation, skip down the document below the Design & Dependencies section.
RKObjectMapping *mapping = [RKObjectMapping mappingForClass:[RKTweet class]];
[mapping addAttributeMappingsFromDictionary:@{
@"user.name": @"username",
@"user.id": @"userID",
@"text": @"text"
}];
Design
-------------------------
RestKit is composed of three main components: **Network**, **Object Mapping**, and **Core Data**. Each layer provides a higher level of abstraction around the problem of accessing web services and representing the data returned as an object. The primary goal of RestKit is to allow the application programmer to think more in terms of their application's data model and less about the details of fetching, parsing, and representing resources. Functionally, each piece provides...
1. **Network** - The network layer provides a request/response abstraction on top of NSURLConnection. The main interface for the end developer is the *RKClient*, which provides an interface for sending GET, POST, PUT, and DELETE requests asynchronously. This wraps the construction and dispatch of *RKRequest* and *RKResponse* objects, that provide a nice interface for working with HTTP requests. Sending parameters with your request is as easy as providing an NSDictionary of key/value pairs. File uploading support from NSData and files is supported through the use of an *RKParams* object, which serializes into a multipart form representation suitable for submission to a remote web server for processing. SSL & HTTP AUTH is fully supported for requests. *RKResponse* objects provide access to the string of JSON parsed versions of the response body in one line of code. There are also a number of helpful method for inspecting the request and response such as isXHTML, isJSON, isRedirect, isOK, etc.
1. **Object Mapping** - The object mapping layer provides a simple API for turning remote JSON/XML responses into local domain objects declaratively. Rather than working directly with *RKClient*, the developer works with *RKObjectManager*. *RKObjectManager* provides support for loading a remote resource path (see below for discussion) and calling back a delegate with object representations of the data loaded. Remote payloads are parsed to an NSDictionary representation and are then mapped to local objects using Key-Value Coding. Any KVC compliant class can be targeted for object mapping. RestKit also provides support for serializing local objects back into a wire format for submission back to your remote backend system. Local domain objects can be serialized to JSON or URL Form Encoded string representations for transport. To simplify the generation of URL's that identify remote resources, RestKit ships with an object routing implementation that can
generate an appropriate URL based on the object and HTTP verb being utilized. Object mapping is a deep topic and is explored thoroughly in the [Object Mapping Design Document].
1. **Core Data** - The Core Data layer provides additional support on top of the object mapper for mapping from remote resources to persist local objects. This is useful for providing offline support, holding on to transient data, and speeding up user interfaces by avoiding expensive trips to the web server. The Core Data support requires that you initialize an instance of *RKManagedObjectStore* and assign it to the *RKObjectManager*. RestKit includes a library of extensions to NSManagedObject that provide an Active Record pattern on top of the Core Data primitives. See the Examples/ subdirectory for examples of how to get this running. The Core Data support also provides *RKManagedObjectSeeder*, a tool for creating a local "seed database" to bootstrap an object model from local JSON files. This allows you to ship an app to the store that already has data pre-loaded and then synchronize with the cloud to keep your clients up to date.
### Base URL and Resource Paths
RestKit utilizes the concepts of the Base URL and resource paths throughout the library. Basically the base URL is a prefix URL that all requests will be sent to. This prevents you from spreading server name details across the code base and repeatedly constructing URL fragments. The *RKClient* and *RKObjectManager* are both initialized with a base URL initially. All other operations dispatched through these objects work of a resource path, which is basically just a URL path fragment that is appended to the base URL before constructing the request. This allows you to switch between development, staging, and production servers very easily and reduces redundancy.
Note that you can send *RKRequest* objects to arbitrary URL's by constructing them yourself.
Parsers
-------------------------
RestKit provides a pluggable parser interface configurable by MIME Type. The standard RestKit distribution includes two parsers:
1. **RKJSONParserJSONKit** - A very fast JSON parser leveraging [JSONKit](http://github.com/johnezang/JSONKit)
1. **RKXMLParserLibXML** - A custom LibXML2 based parser. Only provides parsing, not serialization.
The JSONKit headers can be imported for direct use:
```objc
#import <RestKit/JSONKit.h>
RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:mapping pathPattern:nil keyPath:nil statusCodes:nil];
NSURL *url = [NSURL URLWithString:@"http://api.twitter.com/1/statuses/public_timeline.json"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
RKObjectRequestOperation *operation = [RKObjectRequestOperation objectRequestOperationWithRequest:request responseDescriptors:@[responseDescriptor] success:^(RKObjectRequestOperation *operation, RKMappingResult *result) {
NSLog(@"The public timeline Tweets: %@", [result asCollection]);
} failure:nil];
[operation start];
```
Additional parsers can be added to your RestKit application by linking the parsers into your application and configuring it to handle the appropriate
MIME Type:
## Getting Started
```objc
[[RKParserRegistry sharedRegistry] setParserClass:[SomeOtherParser class] forMIMEType:@"application/json"]];
- [Download RestKit](https://github.com/RestKit/RestKit/downloads) and play with the [examples](https://github.com/RestKit/RestKit/tree/development/Examples) for iPhone and Mac OS X
- First time with RestKit? Read the ["Overview"](#Overview) section below and then check out the ["Getting Acquainted with RestKit"]() tutorial and [Object Mapping Reference](https://github.com/RestKit/RestKit/wiki/Object-mapping) documents in the wiki to jump right in.
- Upgrading from RestKit 0.9.x or 0.10.x? Read the ["Upgrading to RestKit 0.20.x"]() guide in the wiki
- Adding RestKit to an existing [AFNetworking]() application? Read the [AFNetworking Integration]() document to learn details about how the frameworks fit together.
- Review the [source code API documentation](http://restkit.org/api/0.20.0) for a detailed look at the classes and API's in RestKit
- Still need some help? Get support from [Stack Overflow](), the [RestKit mailing list](http://groups.google.com/group/restkit) or ping us on [Twitter](http://twitter.com/RestKit)
## Overview
RestKit is designed to be modular and each module strives to maintain a minimal set of dependencies across the framework and with the host platform. At the core of library sits the object mapping engine, which is responsible for transforming objects between representations (such as JSON/XML <-> local domain objects).
### Object Mapping Fundamentals
The object mapping engine is built on top of the [Key-Value Coding](https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/KeyValueCoding/Articles/KeyValueCoding.html) (KVC) informal protocol that is foundational to numerous Cocoa technologies such as key-value observing, bindings, and Core Data. Object mappings are expressed as pairs of KVC key paths that specify the source and destination attributes or relationships that are to be transformed.
RestKit leverages the highly dynamic Objective-C runtime to infer the developers desired intent by examining the type of the source and destination properties and performing appropriate type transformations. For example, given a source key path of `created_at` that identifies a string within a parsed JSON document and a destination key path of `creationDate` that identifies an `NSDate` property on a target object, RestKit will transform the date from a string into an `NSDate` using an `NSDateFormatter`. Numerous other transformations are provided out of the box and the engine is pluggable to allow the developer to define new transformations or replace an existing transformation with a new implementation.
The mapper fully supports both simple attribute as well as relationship mappings in which nested to-one or to-many child objects are mapped recursively. Through relationship mappings, one object mapping can be added to another to compose aggregate mappings that are capable of processing arbitrarily complex source documents.
Object mapping is a deep topic and is explored in exhaustive detail in the [Object Mapping Guide](https://github.com/RestKit/RestKit/wiki/Object-mapping) on the wiki.
### API Quickstart
RestKit is broken into several modules that cleanly separate the mapping engine from the HTTP and Core Data integrations to provide maximum flexibility. Key classes in each module are highlighted below and each module is hyperlinked to the README.md contained within the source code.
<table>
<tr><th colspan="2" style="text-align:center;"><a href="blob/development/Code/ObjectMapping/README.md">Object Mapping</a></th></tr>
<tr>
<td><a href="http://restkit.org/api/0.20.0/Classes/RKObjectMapping.html">RKObjectMapping</a></td>
<td>Encapsulates configuration for transforming object representations as expressed by key-value coding keypaths.</td>
</tr>
<tr>
<td><a href="http://restkit.org/api/0.20.0/Classes/RKAttributeMapping.html">RKAttributeMapping</a></td>
<td>Specifies a desired transformation between attributes within an object or entity mapping in terms of a source and destination key path.</td>
</tr>
<tr>
<td><a href="http://restkit.org/api/0.20.0/Classes/RKRelationshipMapping.html">RKRelationshipMapping</a></td>
<td>Specifies a desired mapping of a nested to-one or to-many child objects in in terms of a source and destination key path and an <tt>RKObjectMapping</tt> with which to map the attributes of the child object.</td>
</tr>
<tr>
<td><a href="http://restkit.org/api/0.20.0/Classes/RKDynamicMapping.html">RKDynamicMapping</a></td>
<td>Specifies a flexible mapping in which the decision about which <tt>RKObjectMapping</tt> is to be used to process a given document is deferred to run time.</td>
</tr>
<tr>
<td><a href="http://restkit.org/api/0.20.0/Classes/RKObjectMapper.html">RKObjectMapper</a></td>
<td>Provides an interface for mapping a parsed document into a set of local domain objects.</td>
</tr>
<tr>
<td><a href="http://restkit.org/api/0.20.0/Classes/RKObjectMappingOperation.html">RKObjectMappingOperation</a></td>
<td>An <tt>NSOperation</tt> that performs a mapping between object representations using an <tt>RKObjectMapping</tt>.</td>
</tr>
<tr>
<td><a href="http://restkit.org/api/0.20.0/Classes/RKObjectSerializer.html">RKObjectSerializer</a></td>
<td>Performs serialization of a given object into an <tt>NSDictionary</tt> represenation suitable for use as the parameters of an HTTP request.</td>
</tr>
<tr><th colspan="2" style="text-align:center;"><a href="blob/development/Code/Network/README.md">Networking</a></th></tr>
<tr>
<td><a href="http://restkit.org/api/0.20.0/Classes/RKRequestDescriptor.html">RKRequestDescriptor</a></td>
<td>Describes a request that can be sent from the application to a remote web application for a given object type.</td>
</tr>
<tr>
<td><a href="http://restkit.org/api/0.20.0/Classes/RKResponseDescriptor.html">RKResponseDescriptor</a></td>
<td>Describes an object mappable response that may be returned from a remote web application in terms of an object mapping, a key path, a <a href="">SOCKit pattern</a> for matching the URL, and a set of status codes that define the circumstances in which the mapping is appropriate for a given response.</td>
</tr>
<tr>
<td><a href="http://restkit.org/api/0.20.0/Classes/RKObjectRequestOperation.html">RKObjectRequestOperation</a></td>
<td>An <tt>NSOperation</tt> that sends an HTTP request and performs object mapping on the parsed response body using the configurations expressed in a set of <tt>RKResponseDescriptor</tt> objects.</td>
</tr>
<tr>
<td><a href="http://restkit.org/api/0.20.0/Classes/RKResponseMapper.html">RKResponseMapperOperation</a></td>
<td>An <tt>NSOperation</tt> that provides support for object mapping an <tt>NSHTTPURLResponse</tt> using a set of <tt>RKResponseDescriptor</tt> objects.</td>
</tr>
<tr>
<td><a href="http://restkit.org/api/0.20.0/Classes/RKObjectManager.html">RKObjectManager</a></td>
<td>Captures the common patterns for communicating with a RESTful web application over HTTP using object mapping including:
<ul>
<li>Centralizing <tt>RKRequestDescriptor</tt> and <tt>RKResponseDescriptor</tt> configurations</li>
<li>Describing URL configuration with an <tt>RKRouter</tt></li>
<li>Serializing objects and sending requests with the serialized representations</li>
<li>Sending requests to load remote resources and object mapping the response bodies</li>
<li>Building multi-part form requests for objects</li>
</ul>
</td>
</tr>
<tr>
<td><a href="http://restkit.org/api/0.20.0/Classes/RKRouter.html">RKRouter</a></td>
<td>Generates <tt>NSURL</tt> objects from a base URL and a set of <tt>RKRoute</tt> objects describing relative paths used by the application.</td>
</tr>
<tr>
<td><a href="http://restkit.org/api/0.20.0/Classes/RKRoute.html">RKRoute</a></td>
<td>Describes a single relative path for a given object type and HTTP method, the relationship of an object, or a symbolic name.</td>
</tr>
<tr><th colspan="2" style="text-align:center;"><a href="blob/development/Code/CoreData/README.md">Core Data</a></th></tr>
<tr>
<td><a href="http://restkit.org/api/0.20.0/Classes/RKManagedObjectStore.html">RKManagedObjectStore</a></td>
<td>Encapsulates Core Data configuration including an <tt>NSManagedObjectModel</tt>, a <tt>NSPersistentStoreCoordinator</tt>, and a pair of <tt>NSManagedObjectContext</tt> objects.</td>
</tr>
<tr>
<td><a href="http://restkit.org/api/0.20.0/Classes/RKEntityMapping.html">RKEntityMapping</a></td>
<td>Models a mapping for transforming an object representation into a <tt>NSManagedObject</tt> instance for a given <tt>NSEntityDescription</tt>.</td>
</tr>
<tr>
<td><a href="http://restkit.org/api/0.20.0/Classes/RKConnectionMapping.html">RKConnectionMapping</a></td>
<td>Describes a mapping for establishing a relationship between Core Data entities using foreign key attributes.</td>
</tr>
<tr>
<td><a href="http://restkit.org/api/0.20.0/Classes/RKManagedObjectRequestOperation.html">RKManagedObjectRequestOperation</a></td>
<td>An <tt>NSOperation</tt> subclass that sends an HTTP request and performs object mapping on the parsed response body to create <tt>NSManagedObject</tt> instances, establishes relationships between objects using <tt>RKConnectionMapping</tt> objects, and cleans up orphaned objects that no longer exist in the remote backend system.</td>
</tr>
<tr>
<td><a href="http://restkit.org/api/0.20.0/Classes/RKManagedObjectImporter.html">RKManagedObjectImporter</a></td>
<td>Provides support for bulk mapping of managed objects using <tt>RKEntityMapping</tt> objects for two use cases:
<ol>
<li>Bulk importing of parsed documents into an <tt>NSPersistentStore.</tt></li>
<li>Generating a <a href="Docs for database seeding">seed database</a> for initializing an application's Core Data store with an initial data set upon installation.</li>
</ol>
</td>
</tr>
<tr><th colspan="2" style="text-align:center;"><a href="blob/development/Code/Search/README.md">Search</a></th></tr>
<tr>
<td><a href="http://restkit.org/api/0.20.0/Classes/RKSearchIndexer.html">RKSearchIndexer</a></td>
<td>Provides support for generating a full-text searchable index within Core Data for string attributes of entities within an application.</td>
</tr>
<tr>
<td><a href="http://restkit.org/api/0.20.0/Classes/RKSearchPredicate.html">RKSearchPredicate</a></td>
<td>Generates an <tt>NSCompoundPredicate</tt> given a string of text that will search an index built with an <tt>RKSearchIndexer</tt> across any indexed entity.</td>
</tr>
<tr><th colspan="2" style="text-align:center;"><a href="blob/development/Code/Testing/README.md">Testing</a></th></tr>
<tr>
<td><a href="http://restkit.org/api/0.20.0/Classes/RKMappingTest.html">RKMappingTest</a></td>
<td>Provides support for unit testing object mapping configurations given a parsed document and an object or entity mapping. Expectations are configured in terms of expected key path mappings and/or expected transformation results.</td>
</tr>
<tr>
<td><a href="http://restkit.org/api/0.20.0/Classes/RKTestFixture.html">RKTestFixture</a></td>
<td>Provides an interface for easily generating test fixture data for unit testing.</td>
</tr>
<tr>
<td><a href="http://restkit.org/api/0.20.0/Classes/RKTestFactory.html">RKTestFactory</a></td>
<td>Provides support for creating objects for use in testing.</td>
</tr>
</table>
###
## Examples
### Object Request
``` objective-c
// GET a single Article from /articles/1234.json and map it into an object
// JSON looks like {"article": {"title": "My Article", "author": "Blake", "body": "Very cool!!"}}
RKObjectMapping *mapping = [RKObjectMapping mappingForClass:[Article class]];
[mapping addAttributeMappingsFromArray:@[@"title", @"author", @"body"]];
NSIndexSet *statusCodes = RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful); // Anything in 2xx
RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:mapping pathPattern:@"/articles/:articleID" keyPath:@"article" statusCodes:statusCodes];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://restkit.org/articles/1234.json"]];
RKObjectRequestOperation *operation = [[RKObjectRequestOperation alloc] initWithRequest:request responseDescriptors:@[responseDescriptor]];
[operation setCompletionBlockWithSuccess:^(RKObjectRequestOperation *operation, RKMappingResult *result) {
Article *article = [result asObject];
NSLog(@"Mapped the article: %@", article);
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
NSLog(@"Failed with error: %@", [error localizedDescription]);
}];
```
The RestKit project also provides optional additional parsers that can be installed separately from the main library:
### Managed Object Request
``` objective-c
// GET an Article and its Categories from /articles/888.json and map into Core Data entities
// JSON looks like {"article": {"title": "My Article", "author": "Blake", "body": "Very cool!!", "categories": [{"id": 1, "name": "Core Data"]}
NSManagedObjectModel *managedObjectModel = [NSManagedObjectModel mergedModelFromBundles:nil];
RKManagedObjectStore *managedObjectStore = [[RKManagedObjectStore alloc] initWithManagedObjectModel:managedObjectModel];
NSString *path = [RKApplicationDataDirectory() stringByAppendingPathComponent:@"Store.sqlite"];
[managedObjectStore addSQLitePersistentStoreAtPath:path fromSeedDatabaseAtPath:nil error:nil];
[managedObjectStore createManagedObjectContexts];
1. [**RKJSONParserSBJSON**](https://github.com/RestKit/RKJSONParserSBJSON) - A JSON parser built on top of SBJSON
1. [**RKJSONParserYAJL**](https://github.com/RestKit/RKJSONParserYAJL) - A JSON parser built on top of YAJL)
1. [**RKJSONParserNXJSON**](https://github.com/RestKit/RKJSONParserNXJSON) - A JSON parser built on top of the Nextive JSON parser
RKEntityMapping *categoryMapping = [RKEntityMapping mappingForEntityForName:@"Category" inManagedObjectStore:managedObjectStore];
[categoryMapping addAttributeMappingsFromDictionary:@{ "id": "categoryID", @"name": "name" }];
RKEntityMapping *articleMapping = [RKEntityMapping mappingForEntityForName:@"Article" inManagedObjectStore:managedObjectStore];
[articleMapping addAttributeMappingsFromArray:@[@"title", @"author", @"body"]];
[articleMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"categories" toKeyPath:@"categories" withMapping:categoryMapping]];
Documentation & Example Code
-------------------------
NSIndexSet *statusCodes = RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful); // Anything in 2xx
RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:articleMapping pathPattern:@"/articles/:articleID" keyPath:@"article" statusCodes:statusCodes];
Documentation and example code is being added as quickly as possible. Please check the Docs/ and Examples/ subdirectories to see what's available. The [RestKit Google Group](http://groups.google.com/group/restkit) is an invaluable resource for getting help working with the library.
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://restkit.org/articles/888.json"]];
RKManagedObjectRequestOperation *operation = [[RKManagedObjectRequestOperation alloc] initWithRequest:request responseDescriptors:@[responseDescriptor]];
operation.managedObjectContext = managedObjectStore.mainQueueManagedObjectContext;
[operation setCompletionBlockWithSuccess:^(RKObjectRequestOperation *operation, RKMappingResult *result) {
Article *article = [result asObject];
NSLog(@"Mapped the article: %@", article);
NSLog(@"Mapped the category: %@", category);
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
NSLog(@"Failed with error: %@", [error localizedDescription]);
}];
```
RestKit has API documentation available on the web. You can access the documentation in several ways:
### Map a Client Error Response to an NSError
``` objective-c
// GET /articles/error.json returns a 422 (Unprocessable Entity)
// JSON looks like {"errors": "Some Error Has Occurred"}
1. Online in your web browser. Visit http://restkit.org/api/
1. Directly within Xcode. Visit your Xcode Preferences and view the Documentation tab. Click + and add the RestKit feed: feed://restkit.org/api/org.restkit.RestKit.atom
1. Generate the documentation directly from the project source code. Run `rake docs` to generate and `rake docs:install` to install into Xcode
RKObjectMapping *errorMapping = [RKObjectMapping mappingForClass:[RKErrorMessage class]];
// The entire value at the source key path containing the errors maps to the message
[errorMapping addAttributeMapping:[RKAttributeMapping attributeMappingFromKeyPath:[NSNull null] toKeyPath:@"message"]];
Installation
=========================
NSIndexSet *statusCodes = RKStatusCodeIndexSetForClass(RKStatusCodeClassClientError);
// Any response in the 4xx status code range with an "errors" key path uses this mapping
RKResponseDescriptor *errorDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:mapping pathPattern:nil keyPath:@"errors" statusCodes:statusCodes];
Quick Start (aka TL;DR)
-----------
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://restkit.org/articles/error.json"]];
RKObjectRequestOperation *operation = [[RKObjectRequestOperation alloc] initWithRequest:request responseDescriptors:@[errorDescriptor]];
[operation setCompletionBlockWithSuccess:nil failure:^(RKObjectRequestOperation *operation, NSError *error) {
NSLog(@"Loaded this error: %@", [error localizedDescription]);
}];
```
RestKit assumes that you are using a modern Xcode project building to the DerivedData directory. Confirm your settings
via the "File" menu > "Project Settings...". On the "Build" tab within the sheet that opens, click the "Advanced..."
button and confirm that your "Build Location" is the "Derived Data Location".
### Centralize Configuration in an Object Manager
``` objective-c
// Set up Article and Error Response Descriptors
RKObjectMapping *mapping = [RKObjectMapping mappingForClass:[Article class]];
[mapping addAttributeMappingsFromArray:@[@"title", @"author", @"body"]];
NSIndexSet *statusCodes = RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful); // Anything in 2xx
RKResponseDescriptor *articleDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:mapping pathPattern:@"/articles" keyPath:@"article" statusCodes:statusCodes];
1. Add Git submodule to your project: `git submodule add git://github.com/RestKit/RestKit.git RestKit`
1. Add cross-project reference by dragging **RestKit.xcodeproj** to your project
1. Open build settings editor for your project
1. Add the following **Header Search Paths** (including the quotes): `"$(BUILT_PRODUCTS_DIR)/../../Headers"`
1. Add **Other Linker Flags** for `-ObjC -all_load`
1. Open target settings editor for the target you want to link RestKit into
1. Add direct dependency on the **RestKit** aggregate target
1. Link against required frameworks:
1. **CFNetwork.framework** on iOS
1. **CoreData.framework**
1. **Security.framework**
1. **MobileCoreServices.framework** on iOS or **CoreServices.framework** on OS X
1. **SystemConfiguration.framework**
1. **libxml2.dylib**
1. **QuartzCore.framework** on iOS
1. Link against RestKit:
1. **libRestKit.a** on iOS
1. **RestKit.framework** on OS X
1. Import the RestKit headers via `#import <RestKit/RestKit.h>`
1. Build the project to verify installation is successful.
RKObjectMapping *errorMapping = [RKObjectMapping mappingForClass:[RKErrorMessage class]];
// The entire value at the source key path containing the errors maps to the message
[errorMapping addAttributeMapping:[RKAttributeMapping attributeMappingFromKeyPath:[NSNull null] toKeyPath:@"message"]];
NSIndexSet *statusCodes = RKStatusCodeIndexSetForClass(RKStatusCodeClassClientError);
// Any response in the 4xx status code range with an "errors" key path uses this mapping
RKResponseDescriptor *errorDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:mapping pathPattern:nil keyPath:@"errors" statusCodes:statusCodes];
Visual Install Guide
-------------------------
// Add our descriptors to the manager
RKObjectManager *manager = [RKObjectManager managerWithBaseURL:[NSURL URLWithString:@"http://restkit.org"]];
[manager addResponseDescriptorsFromArray:@[ articleDescriptor, errorDescriptor ]];
An step-by-step visual install guide for Xcode 4.x is available on the RestKit Wiki: https://github.com/RestKit/RestKit/wiki/Installing-RestKit-in-Xcode-4.x
[manager getObjectsAtPath:@"/articles/555.json" parameters:nil success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult)) {
// Handled with articleDescriptor
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
// Transport error or server error handled by errorDescriptor
}];
```
Community Resources
-------------------------
### Load a Collection of Objects at a Path
``` objective-c
RKObjectManager *manager = [RKObjectManager managerWithBaseURL:[NSURL URLWithString:@"http://restkit.org"];
[manager getObjectsAtPath:@"/articles" parameters:nil success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult)) {
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
}];
```
A Google Group (high traffic) for development discussions and user support is available at: [http://groups.google.com/group/restkit](http://groups.google.com/group/restkit)
### POST, PATCH, and DELETE an Object
``` objective-c
RKObjectMapping *responseMapping = [RKObjectMapping mappingForClass:[Article class]];
[responseMapping addAttributeMappingsFromArray:@[@"title", @"author", @"body"]];
NSIndexSet *statusCodes = RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful); // Anything in 2xx
RKResponseDescriptor *articleDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:responseMapping pathPattern:@"/articles" keyPath:@"article" statusCodes:statusCodes];
The preferred venue for discussing bugs and feature requests is on Github Issues. The mailing list support traffic can be overwhelming
for our small development team. Please file all bug reports and feature requests at: <https://github.com/RestKit/RestKit/issues>
RKObjectMapping *requestMapping = [RKObjectMapping requestMapping]; // objectClass == NSMutableDictionary
[requestMapping addAttributeMappingsFromArray:@[@"title", @"author", @"body"]];
For users interested in low traffic updates about the library, an announcements list is also available:
[http://groups.google.com/group/restkit-announce](http://groups.google.com/group/restkit-announce)
// For any object of class Article, serialize into an NSMutableDictionary using the given mapping and nest
// under the 'article' key path
RKRequestDescriptor *requestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping:requestMapping objectClass:[Article class] rootKeyPath:@"article"];
Follow RestKit on Twitter:[http://twitter.com/restkit](http://twitter.com/restkit)
RKObjectManager *manager = [RKObjectManager managerWithBaseURL:[NSURL URLWithString:@"http://restkit.org"];
[manager addRequestDescriptor:requestDescriptor];
[manager addResponseDescriptor:responseDescriptor];
Contributing
-------------------------
Article *article = [Article new];
article.title = @"Introduction to RestKit";
article.body = @"This is some text.";
article.author = @"Blake";
Forks, patches and other feedback are always welcome.
// POST to create
[manager postObject:article path:@"/articles" parameters:nil success:nil failure:nil];
Credits
-------------------------
// PATCH to update
article.body = @"New Body";
[manager patchObject:article path:@"/articles/1234" parameters:nil success:nil failure:nil];
// DELETE to destroy
[manager deleteObject:article path:@"/articles/1234" parameters:nil success:nil failure:nil];
```
### Configure Logging
``` objective-c
// Log all HTTP traffic with request and response bodies
RKLogConfigureByName("RestKit/Network", RKLogLevelTrace);
// Log debugging info about Core Data
RKLogConfigureByName("RestKit/CoreData", RKLogLevelDebug);
// Raise logging for a block
RKLogWithLevelWhileExecutingBlock(RKLogLevelTrace, ^{
// Do something that generates logs
});
```
### Configure Routing
``` objective-c
RKObjectManager *manager = [RKObjectManager managerWithBaseURL:[NSURL URLWithString:@"http://restkit.org"];
// Class Routing
[manager.router.routeSet addRoute:[RKRoute routeWithClass:[GGSegment class] pathPattern:@"/segments/:segmentID\\.json" method:RKRequestMethodGET]];
// Relationship Routing
[manager.router.routeSet addRoute:[RKRoute routeWithRelationshipName:@"amenities" objectClass:[GGAirport class] pathPattern:@"/airports/:airportID/amenities.json" method:RKRequestMethodGET]];
// Named Routes
[manager.router.routeSet addRoute:[RKRoute routeWithName:@"thumbs_down_review" resourcePathPattern:@"/reviews/:reviewID/thumbs_down" method:RKRequestMethodPOST]];
```
### POST an Object with a File Attachment
``` objective-c
Article *article = [Article new];
UIImage *image = [UIImage imageNamed:@"some_image.png"];
// Serialize the Article attributes then attach a file
NSMutableURLRequest *request = [[RKObjectManager sharedManager] multipartFormRequestForObject:article method:RKRequestMethodPOST path:nil parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
[formData appendPartWithFileData:UIImagePNGRepresentation(image)
name:@"article[image]"
fileName:@"photo.png"
mimeType:@"image/png"];
}];
RKObjectRequestOperation *operation = [[RKObjectManager sharedManager] objectRequesOperationWithRequest:request success:nil failure:nil];
[operation start];
```
### Generate a Seed Database
``` objective-c
NSManagedObjectModel *managedObjectModel = [NSManagedObjectModel mergedModelFromBundles:nil];
RKManagedObjectStore *managedObjectStore = [[RKManagedObjectStore alloc] initWithManagedObjectModel:managedObjectModel];
RKEntityMapping *articleMapping = [RKEntityMapping mappingForEntityForName:@"Article" inManagedObjectStore:managedObjectStore];
[articleMapping addAttributeMappingsFromArray:@[@"title", @"author", @"body"]];
NSString *seedPath = [RKApplicationDataDirectory() stringByAppendingPathComponent:@"MySeedDatabase.sqlite"];
RKManagedObjectImporter *importer = [[RKManagedObjectImporter alloc] initWithManagedObjectModel:managedObjectStore.managedObjectModel storePath:seedPath];
// Import the files "articles.json" from the Main Bundle using our RKEntityMapping
// JSON looks like {"articles": [ {"title": "Article 1", "body": "Text", "author": "Blake" ]}
NSError *error;
NSBundle *mainBundle = [NSBundle mainBundle];
[importer importObjectsFromItemAtPath:[mainBundle pathForResource:@"articles" ofType:@"json"]
withMapping:articleMapping
keyPath:@"articles"
error:&error];
BOOL success = [importer finishImporting:&error];
if (success) {
[importer logSeedingInfo];
}
```
### Index and Search an Entity
``` objective-c
NSManagedObjectModel *managedObjectModel = [NSManagedObjectModel mergedModelFromBundles:nil];
RKManagedObjectStore *managedObjectStore = [[RKManagedObjectStore alloc] initWithManagedObjectModel:managedObjectModel];
[managedObjectStore addSearchIndexingToEntityForName:@"Article" onAttributes:@[ @"title", @"body" ]];
[managedObjectStore addInMemoryPersistentStore:nil];
[managedObjectStore createManagedObjectContexts];
[managedObjectStore startIndexingPrimaryManagedObjectContext];
Article *article1 = [NSEntityDescription insertNewObjectForEntityForName:@"Article" inManagedObjectContext:managedObjectStore.mainQueueManagedObjectContext];
article1.title = @"First Article";
article1.body = "This should match search";
Article *article2 = [NSEntityDescription insertNewObjectForEntityForName:@"Article" inManagedObjectContext:managedObjectStore.mainQueueManagedObjectContext];
article2.title = @"Second Article";
article2.body = "Does not";
BOOL success = [managedObjectStore.mainQueueManagedObjectContext saveToPersistentStore:nil];
RKSearchPredicate *predicate = [RKSearchPredicate searchPredicateWithText:@"Match" type:NSAndPredicateType];
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Article"];
fetchRequest.predicate = predicate;
// Contains article1 due to body text containing 'match'
NSArray *matches = [managedObjectStore.mainQueueManagedObjectContext executeFetchRequest:fetchRequest error:nil];
NSLog(@"Found the matching articls: %@", matches);
```
### Unit Test a Mapping
``` objective-c
// JSON looks like {"article": {"title": "My Article", "author": "Blake", "body": "Very cool!!"}}
RKObjectMapping *mapping = [RKObjectMapping mappingForClass:[Article class]];
[mapping addAttributeMappingsFromArray:@[@"title", @"author", @"body"]];
NSDictionary *article = @{ @"article": @{ @"title": @"My Title", @"body": @"The article body", @"author": @"Blake" } };
RKMappingTest *mappingTest = [[RKMappingTest alloc] initWithMapping:mapping sourceObject:article destinationObject:nil];
[mappingTest expectMappingFromKeyPath:@"title" toKeyPath:@"title" value:@"My Title"];
[mappingTest performMapping];
[mappingTest verify];
```
## Requirements
RestKit requires [iOS 5.0](http://developer.apple.com/library/ios/#releasenotes/General/WhatsNewIniPhoneOS/Articles/iOS5.html#//apple_ref/doc/uid/TP30915195-SW1) and above or [Mac OS X 10.7](http://developer.apple.com/library/mac/#releasenotes/MacOSX/WhatsNewInOSX/Articles/MacOSX10_7.html#//apple_ref/doc/uid/TP40010355-SW5) and above. It is dependent on [AFNetworking](https://github.com/AFNetworking/AFNetworking) version 0.10.0 above for networking support.
The following Cocoa frameworks must be linked into the application target for proper compilation:
1. **CFNetwork.framework** on iOS
1. **CoreData.framework**
1. **Security.framework**
1. **MobileCoreServices.framework** on iOS or **CoreServices.framework** on OS X
1. **CoreData.framework** (if using Core Data)
### ARC
As of [version 0.20.0](https://github.com/RestKit/RestKit/wiki/Restkit-0.20.0), RestKit has migrated the entire codebase to ARC.
If you are including the RestKit sources directly into a project that does not yet use [Automatic Reference Counting](http://clang.llvm.org/docs/AutomaticReferenceCounting.html), you will need to set the `-fobjc-arc` compiler flag on all of the RestKit source files. To do this in Xcode, go to your active target and select the "Build Phases" tab. Now select all RestKit source files, press Enter, insert `-fobjc-arc` and then "Done" to enable ARC for RestKit.
### Document Coders
RestKit provides a pluggable interface for handling arbitrary document formats via the `[RKCoding](http://restkit.org/api/0.20.0/Classes/RKCoding.html)` protocol and the `[RKCoder](http://restkit.org/api/0.20.0/Classes/RKCoder.html)` class. Out of the box, RestKit supports handling the [JSON](http://www.json.org/) format for serializing and deserializing object representations via the [`NSJSONSerialization`](http://developer.apple.com/library/mac/#documentation/Foundation/Reference/NSJSONSerialization_Class/Reference/Reference.html) class.
#### Additional Coders
Support for additional formats and alternate coding backends is provided via external modules that can be added to the project. Currently the following coders are available for use:
* JSONKit
* SBJSON
* YAJL
* NextiveJson
* XMLReader + XMLWriter
## Installation
The recommended approach for installating RestKit is via the [CocoaPods](http://cocoapods.org/) package manager, as it provides flexible dependency management and dead simple installation.
### via CocoaPods
Install CocoaPods if not already available:
``` bash
$ [sudo] gem install cocoapods
$ pod setup
```
Edit your Podfile and add RestKit:
``` bash
$ edit Podfile
platform :ios
dependency 'RestKit', '0.20.0'
```
Install into your project:
``` bash
$ pod install MyApp.xcodeproj
```
### From a Release Package or as a Git submodule
Detailed installation instructions are available in the [Visual Install Guide](https://github.com/RestKit/RestKit/wiki/Installing-RestKit-in-Xcode-4.x) on the Wiki.
## License
RestKit is licensed under the terms of the [Apache License, version 2.0](http://www.apache.org/licenses/LICENSE-2.0.html). Please see the [LICENSE](https://github.com/RestKit/RestKit/blob/master/LICENSE) file for full details.
## Credits
RestKit is brought to you by [Blake Watters](http://twitter.com/blakewatters) and the RestKit team.
@@ -124,5 +499,3 @@ Support is provided by the following organizations:
* [GateGuru](http://www.gateguruapp.com/)
* [Two Toasters](http://www.twotoasters.com/)
[Object Mapping Design Document]: https://github.com/RestKit/RestKit/blob/master/Docs/Object%20Mapping.md