Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -245,8 +245,8 @@ public void processOpts() {
supportingFiles.add(new SupportingFile("Object-body.mustache", coreFileFolder(), classPrefix + "Object.m"));
supportingFiles.add(new SupportingFile("QueryParamCollection-header.mustache", coreFileFolder(), classPrefix + "QueryParamCollection.h"));
supportingFiles.add(new SupportingFile("QueryParamCollection-body.mustache", coreFileFolder(), classPrefix + "QueryParamCollection.m"));
supportingFiles.add(new SupportingFile("ApiClient-header.mustache", coreFileFolder(), classPrefix + "ApiClient.h"));
supportingFiles.add(new SupportingFile("ApiClient-body.mustache", coreFileFolder(), classPrefix + "ApiClient.m"));
supportingFiles.add(new SupportingFile("ApiSessionManager-header.mustache", coreFileFolder(), classPrefix + "ApiSessionManager.h"));
supportingFiles.add(new SupportingFile("ApiSessionManager-body.mustache", coreFileFolder(), classPrefix + "ApiSessionManager.m"));
supportingFiles.add(new SupportingFile("JSONResponseSerializer-header.mustache", coreFileFolder(), classPrefix + "JSONResponseSerializer.h"));
supportingFiles.add(new SupportingFile("JSONResponseSerializer-body.mustache", coreFileFolder(), classPrefix + "JSONResponseSerializer.m"));
supportingFiles.add(new SupportingFile("JSONRequestSerializer-body.mustache", coreFileFolder(), classPrefix + "JSONRequestSerializer.m"));
Expand All @@ -259,8 +259,11 @@ public void processOpts() {
supportingFiles.add(new SupportingFile("Logger-header.mustache", coreFileFolder(), classPrefix + "Logger.h"));
supportingFiles.add(new SupportingFile("JSONValueTransformer+ISO8601-body.mustache", coreFileFolder(), "JSONValueTransformer+ISO8601.m"));
supportingFiles.add(new SupportingFile("JSONValueTransformer+ISO8601-header.mustache", coreFileFolder(), "JSONValueTransformer+ISO8601.h"));
supportingFiles.add(new SupportingFile("Configuration-body.mustache", coreFileFolder(), classPrefix + "Configuration.m"));
supportingFiles.add(new SupportingFile("Configuration-header.mustache", coreFileFolder(), classPrefix + "Configuration.h"));
supportingFiles.add(new SupportingFile("Configuration-protocol.mustache", coreFileFolder(), classPrefix + "Configuration.h"));
supportingFiles.add(new SupportingFile("DefaultConfiguration-body.mustache", coreFileFolder(), classPrefix + "DefaultConfiguration.m"));
supportingFiles.add(new SupportingFile("DefaultConfiguration-header.mustache", coreFileFolder(), classPrefix + "DefaultConfiguration.h"));
supportingFiles.add(new SupportingFile("BasicAuthTokenProvider-header.mustache", coreFileFolder(), classPrefix + "BasicAuthTokenProvider.h"));
supportingFiles.add(new SupportingFile("BasicAuthTokenProvider-body.mustache", coreFileFolder(), classPrefix + "BasicAuthTokenProvider.m"));
supportingFiles.add(new SupportingFile("api-protocol.mustache", coreFileFolder(), classPrefix + "Api.h"));
supportingFiles.add(new SupportingFile("podspec.mustache", "", podName + ".podspec"));
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
#import "{{classPrefix}}ApiClient.h"
#import <ISO8601/NSDate+ISO8601.h>

#import "{{classPrefix}}ApiSessionManager.h"
#import "{{classPrefix}}JSONRequestSerializer.h"
#import "{{classPrefix}}JSONResponseSerializer.h"
#import "{{classPrefix}}QueryParamCollection.h"
#import "{{classPrefix}}DefaultConfiguration.h"



NSString *const {{classPrefix}}ResponseObjectErrorKey = @"{{classPrefix}}ResponseObject";

static NSUInteger requestId = 0;
static bool offlineState = false;
static NSMutableSet * queuedRequests = nil;
static bool cacheEnabled = false;
static AFNetworkReachabilityStatus reachabilityStatus = AFNetworkReachabilityStatusNotReachable;
static void (^reachabilityChangeBlock)(int);
Expand Down Expand Up @@ -34,40 +40,50 @@ static NSString * {{classPrefix}}__fileNameForResponse(NSURLResponse *response)
}


@interface {{classPrefix}}ApiClient ()
@interface {{classPrefix}}ApiSessionManager ()

@property (nonatomic, strong) NSDictionary* HTTPResponseHeaders;
@property (nonatomic, strong, readwrite) id<{{classPrefix}}Configuration> configuration;

@end

@implementation {{classPrefix}}ApiClient
@implementation {{classPrefix}}ApiSessionManager

- (instancetype)init {
NSString *baseUrl = [[{{classPrefix}}Configuration sharedConfig] host];
return [self initWithBaseURL:[NSURL URLWithString:baseUrl]];

return [self initWithConfiguration:[{{classPrefix}}DefaultConfiguration sharedConfig]];
}

- (instancetype)initWithBaseURL:(NSURL *)url {

return [self initWithBaseURL:url
configuration:[{{classPrefix}}DefaultConfiguration sharedConfig]];

}

- (instancetype)initWithConfiguration:(id<{{classPrefix}}Configuration>)configuration {

return [self initWithBaseURL:[NSURL URLWithString:configuration.host] configuration:configuration];
}

- (instancetype)initWithBaseURL:(NSURL *)url
configuration:(id<{{classPrefix}}Configuration>)configuration {

self = [super initWithBaseURL:url];
if (self) {
self.timeoutInterval = 60;
_configuration = configuration;
_timeoutInterval = 60;
_responseDeserializer = [[{{classPrefix}}ResponseDeserializer alloc] init];
_sanitizer = [[{{classPrefix}}Sanitizer alloc] init];

self.requestSerializer = [AFJSONRequestSerializer serializer];
self.responseSerializer = [AFJSONResponseSerializer serializer];
self.securityPolicy = [self customSecurityPolicy];
self.responseDeserializer = [[{{classPrefix}}ResponseDeserializer alloc] init];
self.sanitizer = [[{{classPrefix}}Sanitizer alloc] init];

// configure reachability
[self configureCacheReachibility];
}
return self;
}

+ (void)initialize {
if (self == [{{classPrefix}}ApiClient class]) {
queuedRequests = [[NSMutableSet alloc] init];
// initialize URL cache
[self configureCacheWithMemoryAndDiskCapacity:4*1024*1024 diskSize:32*1024*1024];
}
return self;
}

#pragma mark - Setter Methods
Expand Down Expand Up @@ -113,43 +129,6 @@ static NSString * {{classPrefix}}__fileNameForResponse(NSURLResponse *response)
[NSURLCache setSharedURLCache:cache];
}

#pragma mark - Request Methods

+(NSUInteger)requestQueueSize {
return [queuedRequests count];
}

+(NSNumber*) nextRequestId {
@synchronized(self) {
return @(++requestId);
}
}

+(NSNumber*) queueRequest {
NSNumber* requestId = [[self class] nextRequestId];
{{classPrefix}}DebugLog(@"added %@ to request queue", requestId);
[queuedRequests addObject:requestId];
return requestId;
}

+(void) cancelRequest:(NSNumber*)requestId {
[queuedRequests removeObject:requestId];
}

-(Boolean) executeRequestWithId:(NSNumber*) requestId {
NSSet* matchingItems = [queuedRequests objectsPassingTest:^BOOL(id obj, BOOL *stop) {
return [obj intValue] == [requestId intValue];
}];

if (matchingItems.count == 1) {
{{classPrefix}}DebugLog(@"removed request id %@", requestId);
[queuedRequests removeObject:requestId];
return YES;
} else {
return NO;
}
}

#pragma mark - Reachability Methods

+(AFNetworkReachabilityStatus) getReachabilityStatus {
Expand All @@ -168,7 +147,7 @@ static NSString * {{classPrefix}}__fileNameForResponse(NSURLResponse *response)
[self.reachabilityManager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
reachabilityStatus = status;
{{classPrefix}}DebugLog(@"reachability changed to %@",AFStringFromNetworkReachabilityStatus(status));
[{{classPrefix}}ApiClient setOfflineState:status == AFNetworkReachabilityStatusUnknown || status == AFNetworkReachabilityStatusNotReachable];
[{{classPrefix}}ApiSessionManager setOfflineState:status == AFNetworkReachabilityStatusUnknown || status == AFNetworkReachabilityStatusNotReachable];

// call the reachability block, if configured
if (reachabilityChangeBlock != nil) {
Expand All @@ -179,23 +158,19 @@ static NSString * {{classPrefix}}__fileNameForResponse(NSURLResponse *response)
[self.reachabilityManager startMonitoring];
}

#pragma mark - Operation Methods
#pragma mark - Task Methods

- (void) operationWithCompletionBlock: (NSURLRequest *)request
requestId: (NSNumber *) requestId
completionBlock: (void (^)(id, NSError *))completionBlock {
__weak __typeof(self)weakSelf = self;
NSURLSessionDataTask* op = [self dataTaskWithRequest:request completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) {
__strong __typeof(weakSelf)strongSelf = weakSelf;
if (![strongSelf executeRequestWithId:requestId]) {
return;
}
- (NSURLSessionDataTask*) taskWithCompletionBlock: (NSURLRequest *)request
completionBlock: (void (^)(id, NSError *))completionBlock {

NSURLSessionDataTask *task = [self dataTaskWithRequest:request completionHandler:^(NSURLResponse * _Nonnull response, id _Nullable responseObject, NSError * _Nullable error) {
{{classPrefix}}DebugLogResponse(response, responseObject,request,error);
strongSelf.HTTPResponseHeaders = {{classPrefix}}__headerFieldsForResponse(response);

if(!error) {
completionBlock(responseObject, nil);
return;
}

NSMutableDictionary *userInfo = [error.userInfo mutableCopy];
if (responseObject) {
// Add in the (parsed) response body.
Expand All @@ -204,20 +179,18 @@ static NSString * {{classPrefix}}__fileNameForResponse(NSURLResponse *response)
NSError *augmentedError = [error initWithDomain:error.domain code:error.code userInfo:userInfo];
completionBlock(nil, augmentedError);
}];
[op resume];

return task;
}

- (void) downloadOperationWithCompletionBlock: (NSURLRequest *)request
requestId: (NSNumber *) requestId
completionBlock: (void (^)(id, NSError *))completionBlock {
__weak __typeof(self)weakSelf = self;
NSURLSessionDataTask* op = [self dataTaskWithRequest:request completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) {
__strong __typeof(weakSelf)strongSelf = weakSelf;
if (![strongSelf executeRequestWithId:requestId]) {
return;
}
strongSelf.HTTPResponseHeaders = {{classPrefix}}__headerFieldsForResponse(response);
- (NSURLSessionDataTask*) downloadTaskWithCompletionBlock: (NSURLRequest *)request
completionBlock: (void (^)(id, NSError *))completionBlock {

id<{{classPrefix}}Configuration> config = self.configuration;

NSURLSessionDataTask* task = [self dataTaskWithRequest:request completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) {
{{classPrefix}}DebugLogResponse(response, responseObject,request,error);

if(error) {
NSMutableDictionary *userInfo = [error.userInfo mutableCopy];
if (responseObject) {
Expand All @@ -226,8 +199,9 @@ static NSString * {{classPrefix}}__fileNameForResponse(NSURLResponse *response)
NSError *augmentedError = [error initWithDomain:error.domain code:error.code userInfo:userInfo];
completionBlock(nil, augmentedError);
}
NSString *directory = [self configuration].tempFolderPath ?: NSTemporaryDirectory();
NSString * filename = {{classPrefix}}__fileNameForResponse(response);

NSString *directory = config.tempFolderPath ?: NSTemporaryDirectory();
NSString *filename = {{classPrefix}}__fileNameForResponse(response);

NSString *filepath = [directory stringByAppendingPathComponent:filename];
NSURL *file = [NSURL fileURLWithPath:filepath];
Expand All @@ -236,24 +210,26 @@ static NSString * {{classPrefix}}__fileNameForResponse(NSURLResponse *response)

completionBlock(file, nil);
}];
[op resume];

return task;
}

#pragma mark - Perform Request Methods

-(NSNumber*) requestWithPath: (NSString*) path
method: (NSString*) method
pathParams: (NSDictionary *) pathParams
queryParams: (NSDictionary*) queryParams
formParams: (NSDictionary *) formParams
files: (NSDictionary *) files
body: (id) body
headerParams: (NSDictionary*) headerParams
authSettings: (NSArray *) authSettings
requestContentType: (NSString*) requestContentType
responseContentType: (NSString*) responseContentType
responseType: (NSString *) responseType
completionBlock: (void (^)(id, NSError *))completionBlock {
#pragma mark - Perform Request Methods

- (NSURLSessionTask*) requestWithPath: (NSString*) path
method: (NSString*) method
pathParams: (NSDictionary *) pathParams
queryParams: (NSDictionary*) queryParams
formParams: (NSDictionary *) formParams
files: (NSDictionary *) files
body: (id) body
headerParams: (NSDictionary*) headerParams
authSettings: (NSArray *) authSettings
requestContentType: (NSString*) requestContentType
responseContentType: (NSString*) responseContentType
responseType: (NSString *) responseType
completionBlock: (void (^)(id, NSError *))completionBlock {

// setting request serializer
if ([requestContentType isEqualToString:@"application/json"]) {
self.requestSerializer = [{{classPrefix}}JSONRequestSerializer serializer];
Expand Down Expand Up @@ -359,14 +335,16 @@ static NSString * {{classPrefix}}__fileNameForResponse(NSURLResponse *response)

[self postProcessRequest:request];

NSNumber* requestId = [{{classPrefix}}ApiClient queueRequest];

NSURLSessionTask *task = nil;

if ([responseType isEqualToString:@"NSURL*"] || [responseType isEqualToString:@"NSURL"]) {
[self downloadOperationWithCompletionBlock:request requestId:requestId completionBlock:^(id data, NSError *error) {
task = [self downloadTaskWithCompletionBlock:request completionBlock:^(id data, NSError *error) {
completionBlock(data, error);
}];
}
else {
[self operationWithCompletionBlock:request requestId:requestId completionBlock:^(id data, NSError *error) {
task = [self taskWithCompletionBlock:request completionBlock:^(id data, NSError *error) {
NSError * serializationError;
id response = [self.responseDeserializer deserialize:data class:responseType error:&serializationError];
if(!response && !error){
Expand All @@ -375,7 +353,10 @@ static NSString * {{classPrefix}}__fileNameForResponse(NSURLResponse *response)
completionBlock(response, error);
}];
}
return requestId;

[task resume];

return task;
}

//Added for easier override to modify request
Expand Down Expand Up @@ -455,10 +436,11 @@ static NSString * {{classPrefix}}__fileNameForResponse(NSURLResponse *response)

NSMutableDictionary *headersWithAuth = [NSMutableDictionary dictionaryWithDictionary:*headers];
NSMutableDictionary *querysWithAuth = [NSMutableDictionary dictionaryWithDictionary:*querys];

NSDictionary* configurationAuthSettings = [[self configuration] authSettings];
id<{{classPrefix}}Configuration> config = self.configuration;
for (NSString *auth in authSettings) {
NSDictionary *authSetting = configurationAuthSettings[auth];
NSDictionary *authSetting = config.authSettings[auth];

if(!authSetting) { // auth setting is set only if the key is non-empty
continue;
}
Expand All @@ -479,11 +461,11 @@ static NSString * {{classPrefix}}__fileNameForResponse(NSURLResponse *response)
- (AFSecurityPolicy *) customSecurityPolicy {
AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeNone];

{{classPrefix}}Configuration *config = [self configuration];
id<{{classPrefix}}Configuration> config = self.configuration;

if (config.sslCaCert) {
NSData *certData = [NSData dataWithContentsOfFile:config.sslCaCert];
[securityPolicy setPinnedCertificates:@[certData]];
[securityPolicy setPinnedCertificates:[NSSet setWithObject:certData]];
}

if (config.verifySSL) {
Expand All @@ -497,8 +479,4 @@ static NSString * {{classPrefix}}__fileNameForResponse(NSURLResponse *response)
return securityPolicy;
}

- ({{classPrefix}}Configuration*) configuration {
return [{{classPrefix}}Configuration sharedConfig];
}

@end
Loading