<commit_before># Overcoat

Overcoat is an [AFNetworking](https://github.com/AFNetworking/AFNetworking) extension that makes it super simple for developers to use Mantle model objects with a REST client.

You can learn more about Mantle [here](https://github.com/github/Mantle/blob/master/README.md).

## Usage

In Overcoat, server API requests are defined by instances of the `OVCQuery` class. Using `OVCQuery` you can specify an HTTP method, a path that identifies the resource, a set of parameters, and a model class.

Servers typically respond to client API request with a dictionary or an array of dictionaries. Overcoat will transparently map those into model objects in a background queue.

For example, using [this](https://github.com/github/Mantle/blob/master/README.md#mtlmodel) model of a GitHub issue, here is how we could use the [GitHub API](http://developer.github.com) to list all the closed issues.

```objc
OVCClient *gitHubClient = [[OVCClient alloc] initWithBaseURL:[NSURL URLWithString:@"https://api.github.com"]];
[gitHubClient setAuthorizationHeaderWithUsername:@"johndoe" password:@"<PASSWORD>"];

OVCQuery *closedIssues = [OVCQuery queryWithMethod:OVCQueryMethodGet path:@"/user/issues" parameters:@{
        @"state" : @"closed"
} modelClass:[GHIssue class]];

[gitHubClient executeQuery:closedIssues completionBlock:^(OVCRequestOperation *operation, NSArray *issues, NSError *error) {
    if (!error) {
        for (GHIssue *issue in issues) {
            NSLog(@"issue: %@ title: %@", issue.number, issue.title);
        }
    }
}];
```

### Social Client

Overcoat features a special client class which can authenticate API requests using an `ACAccount` object on supported social networking services (currently Twitter, Facebook, and Sina Weibo).

Here is how we could lookup for Twitter users.

```objc
@interface TwitterUser : MTLModel

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

@end
```

```objc
@implementation TwitterUser

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

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

@end
```

```objc
OVCSocialClient *twitterClient = [[OVCSocialClient alloc] initWithBaseURL:[NSURL URLWithString:@"https://api.twitter.com/1.1"]];
twitterClient.account = myAccount;

OVCQuery *lookupUsers = [OVCQuery queryWithMethod:OVCQueryMethodGet path:@"/users/lookup.json" parameters:@{
        @"screen_name" : @"twitterapi,twitter"
} modelClass:[TwitterUser class]];

[twitterClient executeQuery:lookupUsers completionBlock:^(OVCRequestOperation *operation, NSArray *users, NSError *error) {
    if (!error) {
        for (TwitterUser *user in users) {
            NSLog(@"name: %@ screenName: %@", user.name, user.screenName);
        }
    }
}];
```

## Contact

[<NAME>](http://github.com/gonzalezreal)  
[@gonzalezreal](https://twitter.com/gonzalezreal)

## License

Overcoat is available under the MIT license. See [LICENSE.md](https://github.com/gonzalezreal/Overcoat/blob/master/LICENSE).
<commit_msg>Update documentation<commit_after># Overcoat

Overcoat is an [AFNetworking](https://github.com/AFNetworking/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](https://github.com/github/Mantle/blob/master/README.md).
2. [Better Web Clients with Mantle and AFNetworking](https://speakerdeck.com/gonzalezreal/better-web-clients-with-mantle-and-afnetworking).

## Example: Searching books in iTunes

We will use the [iTunes Search API](http://www.apple.com/itunes/affiliates/resources/documentation/itunes-store-web-service-search-api.html) to create a class that searches for books in the iTunes Store.

First, lets create a book model using **Mantle**:

```objc
@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;

@end
```

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

```json
{
	"resultCount": 50,
	"results": [{
		"artistId": 3603584,
		"artistName": "<NAME>, <NAME> & <NAME>",
		"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:

```objc
+ (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:

```objc
@interface TGRBookCatalog : OVCClient

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

@end
```

The implementation of `TGRBookCatalog` is pretty simple:

```objc
- (id)init {
    return [super initWithBaseURL:[NSURL URLWithString:@"https://itunes.apple.com"]];
}

- (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:

```objc
[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](https://github.com/gonzalezreal/ReadingList).

### OVCSocialClient

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).

```objc
@interface TwitterUser : MTLModel <MTLJSONSerializing>

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

@end
```

```objc
@implementation TwitterUser

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

@end
```

```objc
OVCSocialClient *twitterClient = [[OVCSocialClient alloc] initWithBaseURL:[NSURL URLWithString:@"https://api.twitter.com/1.1"]];
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.name, user.screenName);
        }
    }
}];
```

## Contact

[<NAME>](http://github.com/gonzalezreal)  
[@gonzalezreal](https://twitter.com/gonzalezreal)

## License

Overcoat is available under the MIT license. See [LICENSE.md](https://github.com/gonzalezreal/Overcoat/blob/master/LICENSE).

{'fraction_non_alphanumeric': 0.1279847182425979, 'fraction_numerical': 0.005942905656372705, 'mean_word_length': 4.820877084620136, 'pattern_counts': {'":': 18, '<': 12, '<?xml version=': 0, '>': 12, 'https://': 15, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6826968', 'n_tokens_mistral': 3019, 'n_tokens_neox': 2784, 'n_words': 841}