Skip to content

Instantly share code, notes, and snippets.

@christianroman
Last active January 1, 2016 02:19
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save christianroman/8078380 to your computer and use it in GitHub Desktop.
Save christianroman/8078380 to your computer and use it in GitHub Desktop.
AFNetworking 2.0, Mantle, NSURLSession API design
//
// CRClient+Requests.h
// CRClient
//
// Created by Christian Roman on 20/12/13.
// Copyright (c) 2013 Christian Roman. All rights reserved.
//
#import "CRClient.h"
#import "CRCompletionBlocks.h"
@interface CRClient (Requests)
- (NSURLSessionDataTask *)requestWithMethod:(NSString *)method
path:(NSString *)path
parameters:(NSDictionary *)parameters
completion:(CRResponseCompletionBlock)completion;
@end
//
// CRClient+Requests.m
// CRClient
//
// Created by Christian Roman on 20/12/13.
// Copyright (c) 2013 Christian Roman. All rights reserved.
//
#import "CRClient+Requests.h"
@implementation CRClient (Requests)
- (NSURLSessionDataTask *)requestWithMethod:(NSString *)method
path:(NSString *)path
parameters:(NSDictionary *)parameters
completion:(CRResponseCompletionBlock)completion
{
NSParameterAssert(method);
NSParameterAssert(path);
NSString *URLString = [[NSURL URLWithString:path relativeToURL:self.baseURL] absoluteString];
NSError *error;
NSURLRequest *request = [[self requestSerializer] requestWithMethod:method URLString:URLString parameters:parameters error:&error];
if(!error) {
NSURLSessionDataTask *task = [self dataTaskWithRequest:request completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) {
if (completion) {
completion((NSHTTPURLResponse *)response, responseObject, error);
}
}];
[task resume];
return task;
}
return nil;
}
@end
//
// CRClient+Stores.h
// CRClient
//
// Created by Christian Roman on 17/12/13.
// Copyright (c) 2013 Christian Roman. All rights reserved.
//
#import "CRClient.h"
#import "CRCompletionBlocks.h"
@interface CRClient (Stores)
- (NSURLSessionDataTask *)getNearbyStoresFromLatitude:(float)latitude
longitude:(float)longitude
completion:(CRArrayCompletionBlock)completion;
@end
//
// CRClient+Stores.m
// CRClient
//
// Created by Christian Roman on 17/12/13.
// Copyright (c) 2013 Christian Roman. All rights reserved.
//
#import "CRClient+Stores.h"
#import "CRClient+Requests.h"
#import "Store.h"
#import "ObjectBuilder.h"
@implementation CRClient (Stores)
- (NSURLSessionDataTask *)getNearbyStoresFromLatitude:(float)latitude
longitude:(float)longitude
completion:(CRArrayCompletionBlock)completion
{
NSParameterAssert(latitude);
NSParameterAssert(longitude);
NSDictionary *parameters = @{
@"languagePreference" : @"es",
@"detailLevel": @2,
@"format" : @"json",
@"radius" : @100,
@"unit" : @1,
@"limit" : @300,
@"longitude" : @(longitude),
@"latitude": @(latitude),
@"brand" : @"stores"
};
NSString *path = @"stores/";
NSString *URLString = [[NSURL URLWithString:path relativeToURL:self.baseURL] absoluteString];
return [self GET:URLString parameters:parameters success:^(NSURLSessionDataTask *task, id responseObject) {
if (!completion) {
return;
}
if (responseObject) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
id collection = [[ObjectBuilder builder] collectionFromJSON:responseObject className:NSStringFromClass([Store class])];
dispatch_async(dispatch_get_main_queue(), ^{
completion(collection, nil);
});
});
} else {
completion(nil, nil);
}
} failure:^(NSURLSessionDataTask *task, NSError *error) {
if (completion) {
completion(nil, error);
}
}];
}
@end
//
// CRClient.h
// CRClient
//
// Created by Christian Roman on 17/12/13.
// Copyright (c) 2013 Christian Roman. All rights reserved.
//
#import "AFNetworking.h"
@interface CRClient : AFHTTPSessionManager
+ (instancetype)sharedClient;
@end
//
// CRClient.m
// CRClient
//
// Created by Christian Roman on 17/12/13.
// Copyright (c) 2013 Christian Roman. All rights reserved.
//
#import "CRClient.h"
@interface CRClient ()
@property (nonatomic, strong) NSString *userAgent;
+ (NSURL *)APIBaseURL;
@end
@implementation CRClient
static NSString * const kCRClientAPIBaseURLString = @"http://api.stores.com/";
#pragma mark - Class Methods
+ (instancetype)sharedClient
{
static dispatch_once_t onceQueue;
static CRClient *__sharedClient = nil;
dispatch_once(&onceQueue, ^{
__sharedClient = [[self alloc] init];
});
return __sharedClient;
}
- (id)init
{
if (self = [super initWithBaseURL:[[self class] APIBaseURL]])
{
self.requestSerializer = [AFHTTPRequestSerializer serializer];
self.responseSerializer = [AFJSONResponseSerializer serializer];
[self.requestSerializer setAuthorizationHeaderFieldWithUsername:@"username" password:@"password"];
}
return self;
}
+ (NSURL *)APIBaseURL
{
return [NSURL URLWithString:kCRClientAPIBaseURLString];
}
@end
//
// CRCompletionBlocks.h
// CRClient
//
// Created by Christian Roman on 20/12/13.
// Copyright (c) 2013 Christian Roman. All rights reserved.
//
typedef void (^CRCompletionBlock)(NSError *error);
typedef void (^CRResponseCompletionBlock)(NSHTTPURLResponse *response, id responseObject, NSError *error);
typedef void (^CRBooleanCompletionBlock)(BOOL result, NSError *error);
typedef void (^CRObjectCompletionBlock)(id object, NSError *error);
typedef void (^CRArrayCompletionBlock)(NSArray *collection, NSError *error);
//...
[[CRClient sharedClient] getNearbyStoresFromLatitude:(float)latitude longitude:(float)longitude completion:^(NSArray *stores, NSError *error) {
if (!error){
NSLog(@"%@", stores);
}
}];
//
// ObjectBuilder.h
// CRClient
//
// Created by Christian Roman on 20/12/13.
// Copyright (c) 2013 Christian Roman. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface ObjectBuilder : NSObject
+ (instancetype)builder;
- (id)objectFromJSON:(NSDictionary *)JSON className:(NSString *)className;
- (id)collectionFromJSON:(NSDictionary *)JSON className:(NSString *)className;
@end
//
// ObjectBuilder.m
// CRClient
//
// Created by Christian Roman on 20/12/13.
// Copyright (c) 2013 Christian Roman. All rights reserved.
//
#import "ObjectBuilder.h"
#import <Mantle/Mantle.h>
@implementation ObjectBuilder
+ (instancetype)builder
{
static dispatch_once_t onceQueue;
static ObjectBuilder *__builder = nil;
dispatch_once(&onceQueue, ^{
__builder = [[ObjectBuilder alloc] init];
});
return __builder;
}
- (id)objectFromJSON:(NSDictionary *)JSON className:(NSString *)className
{
NSParameterAssert(className);
NSError *error = nil;
id model = [MTLJSONAdapter modelOfClass:NSClassFromString(className) fromJSONDictionary:JSON error:&error];
if (!error) {
return model;
} else {
return nil;
}
}
- (id)collectionFromJSON:(NSDictionary *)JSON className:(NSString *)className
{
NSParameterAssert(className);
if ([JSON isKindOfClass:[NSArray class]]) {
NSValueTransformer *valueTransformer = [MTLValueTransformer mtl_JSONArrayTransformerWithModelClass:NSClassFromString(className)];
NSArray *collection = [valueTransformer transformedValue:JSON];
return collection;
}
return nil;
}
@end
//
// Store.h
// Example
//
// Created by Christian Roman on 17/12/13.
// Copyright (c) 2013 Christian Roman. All rights reserved.
//
#import <Mantle/Mantle.h>
@interface Store : MTLModel <MTLJSONSerializing>
@property (nonatomic, copy, readonly) NSString *address1;
@property (nonatomic, copy, readonly) NSString *address2;
@property (nonatomic, copy, readonly) NSString *features;
@property (nonatomic, copy, readonly) NSNumber *ID;
@property (nonatomic, copy, readonly) NSNumber *lat;
@property (nonatomic, copy, readonly) NSNumber *lng;
@property (nonatomic, copy, readonly) NSString *name;
@property (nonatomic, copy, readonly) NSNumber *open24HrsToday;
@property (nonatomic, copy, readonly) NSNumber *openNow;
@property (nonatomic, copy, readonly) NSString *phone;
@property (nonatomic, copy, readonly) NSString *store;
@end
//
// Store.m
// Example
//
// Created by Christian Roman on 17/12/13.
// Copyright (c) 2013 Christian Roman. All rights reserved.
//
#import "Store.h"
@implementation Store
+ (NSDictionary *)JSONKeyPathsByPropertyKey
{
return @{
@"address1" : @"Addr1",
@"address2" : @"Addr2",
@"features" : @"Features",
@"ID": @"Id",
@"lat" : @"Lat",
@"lng" : @"Long",
@"name" : @"Name",
@"open24HrsToday" : @"Open24HrsToday",
@"phone" : @"Phone",
@"store" : @"Store"
};
}
- (NSString *)description
{
return [NSString stringWithFormat:@"<%@: %p, ID: %@, name: %@>", NSStringFromClass([self class]), self, self.ID, self.name];
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment