The perfect accessory for Mantle.
Objective-C C Ruby Shell
Pull request Compare This branch is 364 commits behind Overcoat:master.
Failed to load latest commit information.
AFNetworking @ 259c2c2
Configuration @ 6f6e3af
Mantle @ bd0c716
Overcoat Make account and serviceType properties readonly and add the appropia… Sep 13, 2013
OvercoatTests Make account and serviceType properties readonly and add the appropia… Sep 13, 2013
.gitmodules Re-add OHHTTPStubs under OvercoatTests Sep 6, 2013
.travis.yml Added Travis CI build/test config using xctool. Disabled unused varia… Sep 16, 2013
Overcoat.podspec Update Overcoat.podspec Sep 16, 2013


Build Status

Overcoat is an AFNetworking extension that makes it extremely simple for developers to use Mantle model objects with a REST client.

If you need to learn more about Mantle, we recommend these resources:

  1. Introduction.
  2. Better Web Clients with Mantle and AFNetworking.

Example: Searching books in iTunes

We will use the iTunes Search API to create a class that searches for books in the iTunes Store.

First, lets create a book model using Mantle:

@interface TGRBook : MTLModel <MTLJSONSerializing>

@property (copy, nonatomic, readonly) NSString *author;
@property (copy, nonatomic, readonly) NSString *overview;
@property (copy, nonatomic, readonly) NSArray *genres;
@property (copy, nonatomic, readonly) NSDate *releaseDate;
@property (copy, nonatomic, readonly) NSNumber *identifier;
@property (copy, nonatomic, readonly) NSString *title;
@property (copy, nonatomic, readonly) NSURL *coverURL;


The iTunes Search API will return a JSON with the following format:

	"resultCount": 50,
	"results": [{
		"artistId": 3603584,
		"artistName": "Neil Gaiman, Sam Kieth & Mike Dringenberg",
		"kind": "ebook",
		"price": 1.99,
		"description": "<p>The first issue of the first volume...",
		"currency": "USD",
		"genres": ["Graphic Novels", "Books", "Comics & Graphic Novels"],
		"genreIds": ["10015", "38", "9026"],
		"releaseDate": "2013-05-01T07:00:00Z",
		"trackId": 642469670,
		"trackName": "Sandman #1",

We need to tell our model how to map JSON keys to properties. We can do that by implementing the MTLJSONSerializing protocol:

+ (NSDictionary *)JSONKeyPathsByPropertyKey {
    return @{
            @"author" : @"artistName",
            @"overview" : @"description",
            @"identifier" : @"trackId",
            @"title" : @"trackName",
            @"coverURL" : @"artworkUrl100"

+ (NSValueTransformer *)releaseDateJSONTransformer {
    return [MTLValueTransformer reversibleTransformerWithForwardBlock:^(NSString *str) {
        return [self.dateFormatter dateFromString:str];
    } reverseBlock:^(NSDate *date) {
        return [self.dateFormatter stringFromDate:date];

+ (NSValueTransformer *)coverURLJSONTransformer {
    return [NSValueTransformer valueTransformerForName:MTLURLValueTransformerName];

Once we have the model, we can create an OVCClient subclass that will implement the search method:

@interface TGRBookCatalog : OVCClient

- (void)searchBooksWithTerm:(NSString *)term completion:(void (^)(NSArray *results, NSError *error))block;


The implementation of TGRBookCatalog is pretty simple:

- (id)init {
    return [super initWithBaseURL:[NSURL URLWithString:@""]];

- (void)searchBooksWithTerm:(NSString *)term completion:(void (^)(NSArray *results, NSError *error))block {
    NSDictionary *parameters = @{
            @"term" : term,
            @"entity" : @"ebook"

    [self GET:@"search" parameters:parameters resultClass:TGRBook.class resultKeyPath:@"results" completion:^(AFHTTPRequestOperation *operation, id responseObject, NSError *error) {
        block(responseObject, error);

OVCClient provides methods to make GET, POST and PUT requests specifiying how to map the response to a model object. In this case we are telling OVCClient that we want TGRBook objects that can be found under the key results in the JSON response. OVCRequestOperation makes sure that the mapping from the JSON response to the model or array of model objects happens in a private background queue for performance reasons.

Now we can use TGRBookCatalog to launch a search in iTunes and get an array of TGRBook objects:

[self.bookCatalog searchBooksWithTerm:@"the sandman" completionBlock:^(NSArray *results, NSError *error) {
    if (error == nil) {
        NSLog(@"results: %@", results); // results is an array of TGRBook instances!

You can find the complete example (including TGRBook serialization to a Core Data entity) here.


Overcoat also features an OVCClient subclass that authenticates API requests using an ACAccount object on supported social networking services (currently Twitter, Facebook, and Sina Weibo).

For example, here is how we could lookup for Twitter users (provided that we have an Twitter account).

@interface TwitterUser : MTLModel <MTLJSONSerializing>

@property (copy, nonatomic, readonly) NSString *identifier;
@property (copy, nonatomic, readonly) NSString *name;
@property (copy, nonatomic, readonly) NSString *screenName;

@implementation TwitterUser

+ (NSDictionary *)JSONKeyPathsByPropertyKey {
    return @{
        @"identifier": @"id_str",
        @"screenName": @"screen_name"

OVCSocialClient *twitterClient = [[OVCSocialClient alloc] initWithBaseURL:[NSURL URLWithString:@""]];
twitterClient.account = myAccount;

NSDictionary *parameters = @{
         @"screen_name" : @"twitterapi,twitter"

[self GET:@"users/lookup.json" parameters:parameters resultClass:TwitterUser.class resultKeyPath:nil completion:^(AFHTTPRequestOperation *operation, NSArray *users, NSError *error) {
    if (!error) {
        for (TwitterUser *user in users) {
            NSLog(@"name: %@ screenName: %@",, user.screenName);

Sample Application

ReadingList is a fairly complete iOS example application that shows how to use Overcoat.


Guillermo Gonzalez


Overcoat is available under the MIT license. See