Better Web Clients with
Mantle & AFNetworking
Guillermo González
@gonzalezreal
Mantle
Model framework for Cocoa and Cocoa Touch
https://github.com/github/Mantle
Makes it easy to write a
simple model layer
Gets rid of boilerplate code
Gets rid of boilerplate code
-hash
Gets rid of boilerplate code
-hash
-isEqual:
Gets rid of boilerplate code
-hash
-isEqual:
NSCopying
Gets rid of boilerplate code
-hash
-isEqual:
NSCopying
NSCoding
Example: Book Model
@interface TGRBook : MTLModel

!

@property
@property
@property
@property
@property
@property
@propert...
Example: Book Model
@interface TGRBook : MTLModel

!

@property
@property
@property
@property
@property
@property
@propert...
NSError *error = nil;
TGRBook *book = [TGRBook modelWithDictionary:@{
@"title" : @"The Sandman",
@"author" : @"Neil Gaiman...
NSError *error = nil;
TGRBook *book = [TGRBook modelWithDictionary:@{
@"title" : @"The Sandman",
@"author" : @"Neil Gaiman...
NSError *error = nil;
TGRBook *book = [TGRBook modelWithDictionary:@{
@"title" : @"The Sandman",
@"author" : @"Neil Gaiman...
NSError *error = nil;
TGRBook *book = [TGRBook modelWithDictionary:@{
@"title" : @"The Sandman",
@"author" : @"Neil Gaiman...
(lldb) po book
(lldb) po book
$0 = 0x0a349050 <TGRBook: 0xa349050> {
author = "Neil Gaiman, Sam Keith & Mike Dringenberg";
coverURL = "ht...
All this just by subclassing MTLModel
Our Book Model could
have a JSON representation
Our Book Model could
have a JSON representation
{
...
"artistName": "Neil Gaiman, Sam Keith & Mike Dringenberg",
"descript...
Our Book Model could
have a JSON representation
{
...
"artistName": "Neil Gaiman, Sam Keith & Mike Dringenberg",
"descript...
Our Book Model could
have a JSON representation
{
...
"artistName": "Neil Gaiman, Sam Keith & Mike Dringenberg",
"descript...
MTLJSONSerializing protocol
@interface TGRBook : MTLModel <MTLJSONSerializing>
MTLJSONSerializing protocol
@interface TGRBook : MTLModel <MTLJSONSerializing>

Specify how to map properties to JSON
keyp...
MTLJSONSerializing protocol
@interface TGRBook : MTLModel <MTLJSONSerializing>

Specify how to map properties to JSON
keyp...
+ (NSDictionary *)JSONKeyPathsByPropertyKey {
return @{
@"author" : @"artistName",
@"overview" : @"description",
@"identif...
+ (NSDictionary *)JSONKeyPathsByPropertyKey {
return @{
@"author" : @"artistName",
@"overview" : @"description",
@"identif...
+ (NSDictionary *)JSONKeyPathsByPropertyKey {
return @{
@"author" : @"artistName",
@"overview" : @"description",
@"identif...
+ (NSValueTransformer *)releaseDateJSONTransformer {
return [MTLValueTransformer reversibleTransformerWithForwardBlock:^(N...
+ (NSValueTransformer *)releaseDateJSONTransformer {
return [MTLValueTransformer reversibleTransformerWithForwardBlock:^(N...
+ (NSValueTransformer *)releaseDateJSONTransformer {
return [MTLValueTransformer reversibleTransformerWithForwardBlock:^(N...
+ (NSValueTransformer *)releaseDateJSONTransformer {
return [MTLValueTransformer reversibleTransformerWithForwardBlock:^(N...
Mapping JSON child objects
Mapping JSON child objects
@interface TGRUser : MTLModel <MTLJSONSerializing>

!

@property (copy, nonatomic, readonly) NS...
Mapping JSON child objects
@interface TGRUser : MTLModel <MTLJSONSerializing>

!

@property (copy, nonatomic, readonly) NS...
Mapping JSON child objects
@interface TGRUser : MTLModel <MTLJSONSerializing>

!

@property (copy, nonatomic, readonly) NS...
Mapping JSON child objects
@interface TGRUser : MTLModel <MTLJSONSerializing>

!

@property (copy, nonatomic, readonly) NS...
Mapping JSON child objects
@interface TGRUser : MTLModel <MTLJSONSerializing>

!

@property (copy, nonatomic, readonly) NS...
Mapping JSON child objects
@interface TGRUser : MTLModel <MTLJSONSerializing>

!

@property (copy, nonatomic, readonly) NS...
Mapping JSON child objects
@interface TGRUser : MTLModel <MTLJSONSerializing>

!

@property (copy, nonatomic, readonly) NS...
MTLJSONAdapter
TGRBook *book = [MTLJSONAdapter modelOfClass:TGRBook.class
fromJSONDictionary:JSONDictionary
error:&error];...
Do we still need Core Data?
Do we still need Core Data?
Of course!
Do we still need Core Data?
Of course!
Memory efficiency with large datasets
Do we still need Core Data?
Of course!
Memory efficiency with large datasets
NSFetchRequest is cool!
Do we still need Core Data?
Of course!
Memory efficiency with large datasets
NSFetchRequest is cool!
Mantle and Core Data c...
An entity for our Book Model
MTLManagedObjectSerializing protocol
@interface TGRBook : MTLModel <MTLManagedObjectSerializing>
MTLManagedObjectSerializing protocol
@interface TGRBook : MTLModel <MTLManagedObjectSerializing>

Specify the entity name
MTLManagedObjectSerializing protocol
@interface TGRBook : MTLModel <MTLManagedObjectSerializing>

Specify the entity name
...
MTLManagedObjectSerializing protocol
@interface TGRBook : MTLModel <MTLManagedObjectSerializing>

Specify the entity name
...
+ (NSString *)managedObjectEntityName {
return @"Book";
}

!

+ (NSDictionary *)managedObjectKeysByPropertyKey {
return @{...
MTLManagedObjectAdapter
NSManagedObject *managedBook = [MTLManagedObjectAdapter managedObjectFromModel:book
insertingIntoC...
A delightful iOS and OS X networking framework	

Built on top of Foundation technologies	

Easy to use block-based API	

A...
Example: Search books
NSURL *url = [NSURL URLWithString:@"https://itunes.apple.com"];
AFHTTPClient *client = [[AFHTTPClien...
JSON Response
{
"resultCount": 50,
"results": [{
"artistId": 3603584,
"artistName": "Neil Gaiman, Sam Kieth & Mike Dringen...
Let’s add a Mantle
[client getPath:@"search" parameters:@{
@"term" : @"Neil Gaiman",
@"entity" : @"ebook"
} success:^(AFHT...
Let’s add a Mantle
[client getPath:@"search" parameters:@{
@"term" : @"Neil Gaiman",
@"entity" : @"ebook"
} success:^(AFHT...
NSArray *results = JSONResponse[@"results"];
NSValueTransformer *transformer;
transformer = [NSValueTransformer mtl_JSONAr...
NSArray *results = JSONResponse[@"results"];
NSValueTransformer *transformer;
transformer = [NSValueTransformer mtl_JSONAr...
NSArray *results = JSONResponse[@"results"];
NSValueTransformer *transformer;
transformer = [NSValueTransformer mtl_JSONAr...
NSArray *results = JSONResponse[@"results"];
NSValueTransformer *transformer;
transformer = [NSValueTransformer mtl_JSONAr...
Overcoat
The perfect accessory for Mantle	

Makes it dead simple to use Mantle model
objects with a RESTful client	

AFNet...
Overcoat
OVCRequestOperation
OVCClient
AFJSONRequestOperation
AFHTTPClient
AFHTTPRequestOperation

OVCQuery

OVCSocialClie...
Overcoat 0.x
OVCQuery *query = [OVCQuery queryWithMethod:OVCQueryMethodGet
path:@"search"
parameters:@{
@"term" : term,
@"...
Overcoat 1.0
Overcoat 1.0
NSDictionary *parameters = @{
@"term" : term,
@"entity" : @"ebook"
};

!

[client GET:@"search" parameters:pa...
Overcoat 1.0
NSDictionary *parameters = @{
@"term" : term,
@"entity" : @"ebook"
};

!

[client GET:@"search" parameters:pa...
Overcoat
Server API requests are defined by
OVCQuery objects.	

HTTP method, path, parameters, model
class, multipart data,...
Overcoat
Pull Requests are welcome!
Demo Application
https://github.com/gonzalezreal/ReadingList
Thanks!
Better Web Clients with Mantle and AFNetworking
Upcoming SlideShare
Loading in …5
×

Better Web Clients with Mantle and AFNetworking

6,252 views

Published on

NSCoder Madrid: Talk about how to use Mantle and AFNetworking together. You can find the sample code here https://github.com/gonzalezreal/ReadingList

Published in: Technology
0 Comments
18 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
6,252
On SlideShare
0
From Embeds
0
Number of Embeds
44
Actions
Shares
0
Downloads
84
Comments
0
Likes
18
Embeds 0
No embeds

No notes for slide

Better Web Clients with Mantle and AFNetworking

  1. 1. Better Web Clients with Mantle & AFNetworking
  2. 2. Guillermo González @gonzalezreal
  3. 3. Mantle Model framework for Cocoa and Cocoa Touch
  4. 4. https://github.com/github/Mantle
  5. 5. Makes it easy to write a simple model layer
  6. 6. Gets rid of boilerplate code
  7. 7. Gets rid of boilerplate code -hash
  8. 8. Gets rid of boilerplate code -hash -isEqual:
  9. 9. Gets rid of boilerplate code -hash -isEqual: NSCopying
  10. 10. Gets rid of boilerplate code -hash -isEqual: NSCopying NSCoding
  11. 11. Example: Book Model @interface TGRBook : MTLModel ! @property @property @property @property @property @property @property ! @end (copy, (copy, (copy, (copy, (copy, (copy, (copy, nonatomic, nonatomic, nonatomic, nonatomic, nonatomic, nonatomic, nonatomic, readonly) readonly) readonly) readonly) readonly) readonly) readonly) NSString *author; NSString *overview; NSArray *genres; NSDate *releaseDate; NSNumber *identifier; NSString *title; NSURL *coverURL;
  12. 12. Example: Book Model @interface TGRBook : MTLModel ! @property @property @property @property @property @property @property (copy, (copy, (copy, (copy, (copy, (copy, (copy, nonatomic, nonatomic, nonatomic, nonatomic, nonatomic, nonatomic, nonatomic, readonly) readonly) readonly) readonly) readonly) readonly) readonly) NSString *author; NSString *overview; NSArray *genres; NSDate *releaseDate; NSNumber *identifier; NSString *title; NSURL *coverURL; ! @end Prefer immutable model objects
  13. 13. NSError *error = nil; TGRBook *book = [TGRBook modelWithDictionary:@{ @"title" : @"The Sandman", @"author" : @"Neil Gaiman", @"genres" : @[@"Graphic Novels", @"Fantasy"], ... } error:&error];
  14. 14. NSError *error = nil; TGRBook *book = [TGRBook modelWithDictionary:@{ @"title" : @"The Sandman", @"author" : @"Neil Gaiman", @"genres" : @[@"Graphic Novels", @"Fantasy"], ... } error:&error]; TGRBook *anotherBook = [book copy];
  15. 15. NSError *error = nil; TGRBook *book = [TGRBook modelWithDictionary:@{ @"title" : @"The Sandman", @"author" : @"Neil Gaiman", @"genres" : @[@"Graphic Novels", @"Fantasy"], ... } error:&error]; TGRBook *anotherBook = [book copy]; [NSKeyedArchiver archiveRootObject:book toFile:@"my_file"];
  16. 16. NSError *error = nil; TGRBook *book = [TGRBook modelWithDictionary:@{ @"title" : @"The Sandman", @"author" : @"Neil Gaiman", @"genres" : @[@"Graphic Novels", @"Fantasy"], ... } error:&error]; TGRBook *anotherBook = [book copy]; [NSKeyedArchiver archiveRootObject:book toFile:@"my_file"]; TGRBook *b = [NSKeyedUnarchiver unarchiveObjectWithFile:@"my_file"];
  17. 17. (lldb) po book
  18. 18. (lldb) po book $0 = 0x0a349050 <TGRBook: 0xa349050> { author = "Neil Gaiman, Sam Keith & Mike Dringenberg"; coverURL = "http://a4.mzstatic.com/us/r30/Publication/..."; genres = ( "Graphic Novels", Books, "Comics & Graphic Novels" ); identifier = 554016043; overview = "<p>NEW YORK TIMES bestselling author Neil Gaiman's..."; releaseDate = "2012-08-21 05:00:00 +0000"; title = "The Sandman, Vol. 1: Preludes & Nocturnes (New Edition)"; }
  19. 19. All this just by subclassing MTLModel
  20. 20. Our Book Model could have a JSON representation
  21. 21. Our Book Model could have a JSON representation { ... "artistName": "Neil Gaiman, Sam Keith & Mike Dringenberg", "description": "<p>NEW YORK TIMES bestselling author...", "genres": ["Graphic Novels", "Books", "Comics & Graphic Novels"], "releaseDate": "2012-08-21T07:00:00Z", "trackId": 554016043, "trackName": "The Sandman, Vol. 1: Preludes & Nocturnes (New Edition)", "artworkUrl100": "http://a4.mzstatic.com/us/r30/Publication/...", ... }
  22. 22. Our Book Model could have a JSON representation { ... "artistName": "Neil Gaiman, Sam Keith & Mike Dringenberg", "description": "<p>NEW YORK TIMES bestselling author...", "genres": ["Graphic Novels", "Books", "Comics & Graphic Novels"], "releaseDate": "2012-08-21T07:00:00Z", "trackId": 554016043, "trackName": "The Sandman, Vol. 1: Preludes & Nocturnes (New Edition)", "artworkUrl100": "http://a4.mzstatic.com/us/r30/Publication/...", ... } This is how iTunes represents media (including books)
  23. 23. Our Book Model could have a JSON representation { ... "artistName": "Neil Gaiman, Sam Keith & Mike Dringenberg", "description": "<p>NEW YORK TIMES bestselling author...", "genres": ["Graphic Novels", "Books", "Comics & Graphic Novels"], "releaseDate": "2012-08-21T07:00:00Z", "trackId": 554016043, "trackName": "The Sandman, Vol. 1: Preludes & Nocturnes (New Edition)", "artworkUrl100": "http://a4.mzstatic.com/us/r30/Publication/...", ... } This is how iTunes represents media (including books) See http://www.apple.com/itunes/affiliates/resources/ documentation/itunes-store-web-service-search-api.html
  24. 24. MTLJSONSerializing protocol @interface TGRBook : MTLModel <MTLJSONSerializing>
  25. 25. MTLJSONSerializing protocol @interface TGRBook : MTLModel <MTLJSONSerializing> Specify how to map properties to JSON keypaths
  26. 26. MTLJSONSerializing protocol @interface TGRBook : MTLModel <MTLJSONSerializing> Specify how to map properties to JSON keypaths Specify how to convert a JSON value to a property key
  27. 27. + (NSDictionary *)JSONKeyPathsByPropertyKey { return @{ @"author" : @"artistName", @"overview" : @"description", @"identifier" : @"trackId", @"title" : @"trackName", @"coverURL" : @"artworkUrl100" }; }
  28. 28. + (NSDictionary *)JSONKeyPathsByPropertyKey { return @{ @"author" : @"artistName", @"overview" : @"description", @"identifier" : @"trackId", @"title" : @"trackName", @"coverURL" : @"artworkUrl100" }; } Only properties with a corresponding ivar
  29. 29. + (NSDictionary *)JSONKeyPathsByPropertyKey { return @{ @"author" : @"artistName", @"overview" : @"description", @"identifier" : @"trackId", @"title" : @"trackName", @"coverURL" : @"artworkUrl100" }; } Only properties with a corresponding ivar Property keys not present in the dictionary are assumed to match the JSON
  30. 30. + (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]; }
  31. 31. + (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]; } +<key>JSONTransformer methods
  32. 32. + (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]; } +<key>JSONTransformer MTLValueTransformer methods is a block-based value transformer
  33. 33. + (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]; } +<key>JSONTransformer MTLValueTransformer methods is a block-based value transformer Predefined transformers: MTLURLValueTransformerName and MTLBooleanValueTransformerName
  34. 34. Mapping JSON child objects
  35. 35. Mapping JSON child objects @interface TGRUser : MTLModel <MTLJSONSerializing> ! @property (copy, nonatomic, readonly) NSArray *purchasedBooks; @property (copy, nonatomic, readonly) TGRBook *nowReading; ! @end
  36. 36. Mapping JSON child objects @interface TGRUser : MTLModel <MTLJSONSerializing> ! @property (copy, nonatomic, readonly) NSArray *purchasedBooks; @property (copy, nonatomic, readonly) TGRBook *nowReading; ! @end + (NSValueTransformer *)purchasedBooksJSONTransformer {
  37. 37. Mapping JSON child objects @interface TGRUser : MTLModel <MTLJSONSerializing> ! @property (copy, nonatomic, readonly) NSArray *purchasedBooks; @property (copy, nonatomic, readonly) TGRBook *nowReading; ! @end + (NSValueTransformer *)purchasedBooksJSONTransformer { return [NSValueTransformer mtl_JSONArrayTransformerWithModelClass:TGRBook.class];
  38. 38. Mapping JSON child objects @interface TGRUser : MTLModel <MTLJSONSerializing> ! @property (copy, nonatomic, readonly) NSArray *purchasedBooks; @property (copy, nonatomic, readonly) TGRBook *nowReading; ! @end + (NSValueTransformer *)purchasedBooksJSONTransformer { return [NSValueTransformer mtl_JSONArrayTransformerWithModelClass:TGRBook.class]; }
  39. 39. Mapping JSON child objects @interface TGRUser : MTLModel <MTLJSONSerializing> ! @property (copy, nonatomic, readonly) NSArray *purchasedBooks; @property (copy, nonatomic, readonly) TGRBook *nowReading; ! @end + (NSValueTransformer *)purchasedBooksJSONTransformer { return [NSValueTransformer mtl_JSONArrayTransformerWithModelClass:TGRBook.class]; }
  40. 40. Mapping JSON child objects @interface TGRUser : MTLModel <MTLJSONSerializing> ! @property (copy, nonatomic, readonly) NSArray *purchasedBooks; @property (copy, nonatomic, readonly) TGRBook *nowReading; ! @end + (NSValueTransformer *)purchasedBooksJSONTransformer { return [NSValueTransformer mtl_JSONArrayTransformerWithModelClass:TGRBook.class]; } + (NSValueTransformer *)nowReadingJSONTransformer {
  41. 41. Mapping JSON child objects @interface TGRUser : MTLModel <MTLJSONSerializing> ! @property (copy, nonatomic, readonly) NSArray *purchasedBooks; @property (copy, nonatomic, readonly) TGRBook *nowReading; ! @end + (NSValueTransformer *)purchasedBooksJSONTransformer { return [NSValueTransformer mtl_JSONArrayTransformerWithModelClass:TGRBook.class]; } + (NSValueTransformer *)nowReadingJSONTransformer { return [NSValueTransformer mtl_JSONDictionaryTransformerWithModelClass:TGRBook.class];
  42. 42. MTLJSONAdapter TGRBook *book = [MTLJSONAdapter modelOfClass:TGRBook.class fromJSONDictionary:JSONDictionary error:&error]; ! ! NSDictionary *dictionary = [MTLJSONAdapter JSONDictionaryFromModel:book];
  43. 43. Do we still need Core Data?
  44. 44. Do we still need Core Data? Of course!
  45. 45. Do we still need Core Data? Of course! Memory efficiency with large datasets
  46. 46. Do we still need Core Data? Of course! Memory efficiency with large datasets NSFetchRequest is cool!
  47. 47. Do we still need Core Data? Of course! Memory efficiency with large datasets NSFetchRequest is cool! Mantle and Core Data can work together
  48. 48. An entity for our Book Model
  49. 49. MTLManagedObjectSerializing protocol @interface TGRBook : MTLModel <MTLManagedObjectSerializing>
  50. 50. MTLManagedObjectSerializing protocol @interface TGRBook : MTLModel <MTLManagedObjectSerializing> Specify the entity name
  51. 51. MTLManagedObjectSerializing protocol @interface TGRBook : MTLModel <MTLManagedObjectSerializing> Specify the entity name Specify how to map properties to managed object attributes
  52. 52. MTLManagedObjectSerializing protocol @interface TGRBook : MTLModel <MTLManagedObjectSerializing> Specify the entity name Specify how to map properties to managed object attributes Specify how to convert a managed object attribute value to a property key
  53. 53. + (NSString *)managedObjectEntityName { return @"Book"; } ! + (NSDictionary *)managedObjectKeysByPropertyKey { return @{ @"coverURL" : @"coverLink" }; } ! + (NSValueTransformer *)coverURLEntityAttributeTransformer { return [[NSValueTransformer valueTransformerForName:MTLURLValueTransformerName] mtl_invertedTransformer]; }
  54. 54. MTLManagedObjectAdapter NSManagedObject *managedBook = [MTLManagedObjectAdapter managedObjectFromModel:book insertingIntoContext:moc error:&error]; ! ! ! TGRBook *book = [MTLManagedObjectAdapter modelOfClass:TGRBook.class fromManagedObject:object error:&error];
  55. 55. A delightful iOS and OS X networking framework Built on top of Foundation technologies Easy to use block-based API Amazing community of developers Used by some of the most popular apps on iOS and OSX https://github.com/AFNetworking/AFNetworking
  56. 56. Example: Search books NSURL *url = [NSURL URLWithString:@"https://itunes.apple.com"]; AFHTTPClient *client = [[AFHTTPClient alloc] initWithBaseURL:url]; ! [client getPath:@"search" parameters:@{ @"term" : @"the sandman", @"entity" : @"ebook" } success:^(AFHTTPRequestOperation *operation, id JSONResponse) { NSLog(@"Search results: %@", JSONResponse); } failure:^(AFHTTPRequestOperation *operation, NSError *error) { ... }];
  57. 57. JSON Response { "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", ...
  58. 58. Let’s add a Mantle [client getPath:@"search" parameters:@{ @"term" : @"Neil Gaiman", @"entity" : @"ebook" } success:^(AFHTTPRequestOperation *operation, NSDictionary *JSONResponse) { ! ! NSArray *results = JSONResponse[@"results"]; NSValueTransformer *transformer; transformer = [NSValueTransformer mtl_JSONArrayTransformerWithModelClass:TGRBook.class]; NSArray *books = [transformer transformedValue:results]; NSLog(@"Books: %@", books); } failure:^(AFHTTPRequestOperation *operation, NSError *error) { ... }];
  59. 59. Let’s add a Mantle [client getPath:@"search" parameters:@{ @"term" : @"Neil Gaiman", @"entity" : @"ebook" } success:^(AFHTTPRequestOperation *operation, NSDictionary *JSONResponse) { ! ! NSArray *results = JSONResponse[@"results"]; NSValueTransformer *transformer; transformer = [NSValueTransformer mtl_JSONArrayTransformerWithModelClass:TGRBook.class]; NSArray *books = [transformer transformedValue:results]; NSLog(@"Books: %@", books); } failure:^(AFHTTPRequestOperation *operation, NSError *error) { ... }];
  60. 60. NSArray *results = JSONResponse[@"results"]; NSValueTransformer *transformer; transformer = [NSValueTransformer mtl_JSONArrayTransformerWithModelClass:TGRBook.class]; NSArray *books = [transformer transformedValue:results];
  61. 61. NSArray *results = JSONResponse[@"results"]; NSValueTransformer *transformer; transformer = [NSValueTransformer mtl_JSONArrayTransformerWithModelClass:TGRBook.class]; NSArray *books = [transformer transformedValue:results]; Mapping can potentially take time
  62. 62. NSArray *results = JSONResponse[@"results"]; NSValueTransformer *transformer; transformer = [NSValueTransformer mtl_JSONArrayTransformerWithModelClass:TGRBook.class]; NSArray *books = [transformer transformedValue:results]; Mapping can potentially take time It should be done in a background queue
  63. 63. NSArray *results = JSONResponse[@"results"]; NSValueTransformer *transformer; transformer = [NSValueTransformer mtl_JSONArrayTransformerWithModelClass:TGRBook.class]; NSArray *books = [transformer transformedValue:results]; Mapping can potentially take time It should be done in a background queue Boilerplate code again!
  64. 64. Overcoat The perfect accessory for Mantle Makes it dead simple to use Mantle model objects with a RESTful client AFNetworking extension https://github.com/gonzalezreal/Overcoat
  65. 65. Overcoat OVCRequestOperation OVCClient AFJSONRequestOperation AFHTTPClient AFHTTPRequestOperation OVCQuery OVCSocialClien
  66. 66. Overcoat 0.x OVCQuery *query = [OVCQuery queryWithMethod:OVCQueryMethodGet path:@"search" parameters:@{ @"term" : term, @"entity" : @"ebook" } modelClass:TGRBook.class objectKeyPath:@"results"]; ! [client executeQuery:query completionBlock:^(OVCRequestOperation *operation, NSArray *books, NSError *error) { NSLog(@"Books: %@", books); }];
  67. 67. Overcoat 1.0
  68. 68. Overcoat 1.0 NSDictionary *parameters = @{ @"term" : term, @"entity" : @"ebook" }; ! [client GET:@"search" parameters:parameters resultClass:TGRBook.class resultKeyPath:@"results" completion:^(AFHTTPRequestOperation *operation, NSArray *books, NSError *error) { NSLog(@"Books: %@", books); }];
  69. 69. Overcoat 1.0 NSDictionary *parameters = @{ @"term" : term, @"entity" : @"ebook" }; ! [client GET:@"search" parameters:parameters resultClass:TGRBook.class resultKeyPath:@"results" completion:^(AFHTTPRequestOperation *operation, NSArray *books, NSError *error) { NSLog(@"Books: %@", books); }]; Coming soon...
  70. 70. Overcoat Server API requests are defined by OVCQuery objects. HTTP method, path, parameters, model class, multipart data, etc. Maps JSON into model(s) In a private background queue
  71. 71. Overcoat Pull Requests are welcome!
  72. 72. Demo Application https://github.com/gonzalezreal/ReadingList
  73. 73. Thanks!

×