Skip to content

Instantly share code, notes, and snippets.

@mitchellporter
Forked from skunkworks/NPClientAPI.h
Created August 29, 2014 19:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mitchellporter/74d3d584bf360a46986e to your computer and use it in GitHub Desktop.
Save mitchellporter/74d3d584bf360a46986e to your computer and use it in GitHub Desktop.
@interface NPClientAPI : AFHTTPSessionManager
- (instancetype)initWithBaseURL:(NSString *)baseURL;
/**
Singleton object.
*/
+ (NPClientAPI *)sharedAPI;
/**
Fetches topics. Array of @c NPTopic objects.
*/
- (NSURLSessionDataTask *)fetchTopicsOnSuccess:(void (^)(NSURLSessionDataTask *task, NSArray *topics))success failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure;
@end
@implementation NPClientAPI
NSString *const NPClientAPITopicsIndexURI = @"mobile/topics.json";
#pragma mark - Singleton
+ (NPClientAPI *)sharedAPI
{
static NPClientAPI *sharedClientAPI;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedClientAPI = [[self alloc] initWithBaseURL:[NSURL URLWithString:NP_BASE_URL]];
});
return sharedClientAPI;
}
#pragma mark - Lifecycle
- (instancetype)initWithBaseURL:(NSURL *)baseURL
{
if (self = [super initWithBaseURL:baseURL]) {
// Note: probably not necessary, since each API call will set the request/response serializers to custom subclasses
self.requestSerializer = [AFJSONRequestSerializer serializer];
self.responseSerializer = [AFJSONResponseSerializer serializer];
}
return self;
}
#pragma mark - Public methods
- (NSURLSessionDataTask *)fetchTopicsOnSuccess:(void (^)(NSURLSessionDataTask *task, NSArray *topics))success failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure
{
// Set up the response serializer to our custom serializer
self.responseSerializer = [NPTopicsSerializer serializer];
NSURL *url = [NSURL URLWithString:NPClientAPITopicsIndexURI relativeToURL:self.baseURL];
NSURLSessionDataTask *task = [self GET:[url absoluteString] parameters:nil success:^(NSURLSessionDataTask *task, id responseObject) {
if (success) success(task, responseObject);
} failure:^(NSURLSessionDataTask *task, NSError *error) {
// Just a random note: it's a good practice to wrap NSError objects to provide more context
// about the type of failure
NSError *wrappedError = [NSError errorWithDomain:NPClientAPIErrorDomain code:NPClientAPIErrorTypeNetworkIssue userInfo:@{ NSUnderlyingErrorKey : error, NSLocalizedDescriptionKey : @"Failed to fetch topics" }];
if (failure) failure(task, wrappedError);
}];
return task;
}
@end
#import <Mantle/Mantle.h>
@interface NPTopic : MTLModel <MTLJSONSerializing>
@property (strong, nonatomic) NSNumber *identifier;
@property (strong, nonatomic) NSString *name;
@end
@implementation NPTopic
#pragma mark - Protocol conformance
#pragma mark MTLJSONSerializing
// This is a Mantle method override. It's a declarative method that maps the NPTopic object's
// property names to their equivalent JSON key name.
+ (NSDictionary *)JSONKeyPathsByPropertyKey
{
return @{@"identifier" : @"id",
@"name" : @"name"
};
}
@end
#import "AFURLResponseSerialization.h"
@interface NPTopicsSerializer : AFJSONResponseSerializer
@end
#import "NPTopicsSerializer.h"
#import "NPTopic.h"
@implementation NPTopicsSerializer
// Returns array of @c NPTopic objects
- (id)responseObjectForResponse:(NSURLResponse *)response data:(NSData *)data error:(NSError *__autoreleasing *)error
{
NSDictionary *JSONDictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:error];
if (!JSONDictionary) return nil;
// Note: the expected JSON format of this response is { data: [ { <a topic> }, { <another topic>} ], metadata: { ...} }
NSArray *JSONTopics = JSONDictionary[@"data"];
NSMutableArray *topics = [NSMutableArray array];
for (NSDictionary *JSONTopic in JSONTopics) {
// For each topic in JSON format, we can deserialize it from JSON to our desired model class using Mantle
NPTopic *topic = [MTLJSONAdapter modelOfClass:[NPTopic class] fromJSONDictionary:JSONTopic error:error];
if (!topic) return nil;
[topics addObject:topic];
}
*error = nil;
return [topics copy];
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment