Files
openapi-generator/modules/swagger-codegen/src/main/resources/objc/ApiClient-body.mustache
2016-06-05 22:28:56 +08:00

505 lines
20 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#import "{{classPrefix}}ApiClient.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);
static NSDictionary * {{classPrefix}}__headerFieldsForResponse(NSURLResponse *response) {
if(![response isKindOfClass:[NSHTTPURLResponse class]]) {
return nil;
}
return ((NSHTTPURLResponse*)response).allHeaderFields;
}
static NSString * {{classPrefix}}__fileNameForResponse(NSURLResponse *response) {
NSDictionary * headers = {{classPrefix}}__headerFieldsForResponse(response);
if(!headers[@"Content-Disposition"]) {
return [NSString stringWithFormat:@"%@", [[NSProcessInfo processInfo] globallyUniqueString]];
}
NSString *pattern = @"filename=['\"]?([^'\"\\s]+)['\"]?";
NSRegularExpression *regexp = [NSRegularExpression regularExpressionWithPattern:pattern
options:NSRegularExpressionCaseInsensitive
error:nil];
NSString *contentDispositionHeader = headers[@"Content-Disposition"];
NSTextCheckingResult *match = [regexp firstMatchInString:contentDispositionHeader
options:0
range:NSMakeRange(0, [contentDispositionHeader length])];
return [contentDispositionHeader substringWithRange:[match rangeAtIndex:1]];
}
@interface {{classPrefix}}ApiClient ()
@property (nonatomic, strong) NSDictionary* HTTPResponseHeaders;
@end
@implementation {{classPrefix}}ApiClient
- (instancetype)init {
NSString *baseUrl = [[{{classPrefix}}Configuration sharedConfig] host];
return [self initWithBaseURL:[NSURL URLWithString:baseUrl]];
}
- (instancetype)initWithBaseURL:(NSURL *)url {
self = [super initWithBaseURL:url];
if (self) {
self.timeoutInterval = 60;
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];
}
}
#pragma mark - Setter Methods
+ (void) setOfflineState:(BOOL) state {
offlineState = state;
}
+ (void) setCacheEnabled:(BOOL)enabled {
cacheEnabled = enabled;
}
+(void) setReachabilityStatus:(AFNetworkReachabilityStatus)status {
reachabilityStatus = status;
}
- (void)setHeaderValue:(NSString*) value forKey:(NSString*) forKey {
[self.requestSerializer setValue:value forHTTPHeaderField:forKey];
}
- (void)setRequestSerializer:(AFHTTPRequestSerializer<AFURLRequestSerialization> *)requestSerializer {
[super setRequestSerializer:requestSerializer];
requestSerializer.timeoutInterval = self.timeoutInterval;
}
#pragma mark - Cache Methods
+(void)clearCache {
[[NSURLCache sharedURLCache] removeAllCachedResponses];
}
+(void)configureCacheWithMemoryAndDiskCapacity: (unsigned long) memorySize
diskSize: (unsigned long) diskSize {
NSAssert(memorySize > 0, @"invalid in-memory cache size");
NSAssert(diskSize >= 0, @"invalid disk cache size");
NSURLCache *cache =
[[NSURLCache alloc]
initWithMemoryCapacity:memorySize
diskCapacity:diskSize
diskPath:@"swagger_url_cache"];
[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 {
return reachabilityStatus;
}
+(BOOL) getOfflineState {
return offlineState;
}
+(void) setReachabilityChangeBlock:(void(^)(int))changeBlock {
reachabilityChangeBlock = changeBlock;
}
- (void) configureCacheReachibility {
[self.reachabilityManager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
reachabilityStatus = status;
{{classPrefix}}DebugLog(@"reachability changed to %@",AFStringFromNetworkReachabilityStatus(status));
[{{classPrefix}}ApiClient setOfflineState:status == AFNetworkReachabilityStatusUnknown || status == AFNetworkReachabilityStatusNotReachable];
// call the reachability block, if configured
if (reachabilityChangeBlock != nil) {
reachabilityChangeBlock(status);
}
}];
[self.reachabilityManager startMonitoring];
}
#pragma mark - Operation 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;
}
{{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.
userInfo[{{classPrefix}}ResponseObjectErrorKey] = responseObject;
}
NSError *augmentedError = [error initWithDomain:error.domain code:error.code userInfo:userInfo];
completionBlock(nil, augmentedError);
}];
[op resume];
}
- (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);
{{classPrefix}}DebugLogResponse(response, responseObject,request,error);
if(error) {
NSMutableDictionary *userInfo = [error.userInfo mutableCopy];
if (responseObject) {
userInfo[{{classPrefix}}ResponseObjectErrorKey] = responseObject;
}
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 *filepath = [directory stringByAppendingPathComponent:filename];
NSURL *file = [NSURL fileURLWithPath:filepath];
[responseObject writeToURL:file atomically:YES];
completionBlock(file, nil);
}];
[op resume];
}
#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 {
// setting request serializer
if ([requestContentType isEqualToString:@"application/json"]) {
self.requestSerializer = [{{classPrefix}}JSONRequestSerializer serializer];
}
else if ([requestContentType isEqualToString:@"application/x-www-form-urlencoded"]) {
self.requestSerializer = [AFHTTPRequestSerializer serializer];
}
else if ([requestContentType isEqualToString:@"multipart/form-data"]) {
self.requestSerializer = [AFHTTPRequestSerializer serializer];
}
else {
self.requestSerializer = [AFHTTPRequestSerializer serializer];
NSAssert(NO, @"Unsupported request type %@", requestContentType);
}
// setting response serializer
if ([responseContentType isEqualToString:@"application/json"]) {
self.responseSerializer = [{{classPrefix}}JSONResponseSerializer serializer];
} else {
self.responseSerializer = [AFHTTPResponseSerializer serializer];
}
// sanitize parameters
pathParams = [self.sanitizer sanitizeForSerialization:pathParams];
queryParams = [self.sanitizer sanitizeForSerialization:queryParams];
headerParams = [self.sanitizer sanitizeForSerialization:headerParams];
formParams = [self.sanitizer sanitizeForSerialization:formParams];
if(![body isKindOfClass:[NSData class]]) {
body = [self.sanitizer sanitizeForSerialization:body];
}
// auth setting
[self updateHeaderParams:&headerParams queryParams:&queryParams WithAuthSettings:authSettings];
NSMutableString *resourcePath = [NSMutableString stringWithString:path];
[pathParams enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
NSString * safeString = ([obj isKindOfClass:[NSString class]]) ? obj : [NSString stringWithFormat:@"%@", obj];
safeString = {{classPrefix}}PercentEscapedStringFromString(safeString);
[resourcePath replaceCharactersInRange:[resourcePath rangeOfString:[NSString stringWithFormat:@"{%@}", key]] withString:safeString];
}];
NSMutableURLRequest * request = nil;
NSString* pathWithQueryParams = [self pathWithQueryParamsToString:resourcePath queryParams:queryParams];
if ([pathWithQueryParams hasPrefix:@"/"]) {
pathWithQueryParams = [pathWithQueryParams substringFromIndex:1];
}
NSString* urlString = [[NSURL URLWithString:pathWithQueryParams relativeToURL:self.baseURL] absoluteString];
if (files.count > 0) {
__weak __typeof(self)weakSelf = self;
request = [self.requestSerializer multipartFormRequestWithMethod:@"POST"
URLString:urlString
parameters:nil
constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
[formParams enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
NSString *objString = [weakSelf.sanitizer parameterToString:obj];
NSData *data = [objString dataUsingEncoding:NSUTF8StringEncoding];
[formData appendPartWithFormData:data name:key];
}];
[files enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
NSURL *filePath = (NSURL *)obj;
[formData appendPartWithFileURL:filePath name:key error:nil];
}];
} error:nil];
}
else {
if (formParams) {
request = [self.requestSerializer requestWithMethod:method
URLString:urlString
parameters:formParams
error:nil];
}
if (body) {
request = [self.requestSerializer requestWithMethod:method
URLString:urlString
parameters:body
error:nil];
}
}
// request cache
BOOL hasHeaderParams = [headerParams count] > 0;
if (offlineState) {
{{classPrefix}}DebugLog(@"%@ cache forced", resourcePath);
[request setCachePolicy:NSURLRequestReturnCacheDataDontLoad];
}
else if(!hasHeaderParams && [method isEqualToString:@"GET"] && cacheEnabled) {
{{classPrefix}}DebugLog(@"%@ cache enabled", resourcePath);
[request setCachePolicy:NSURLRequestUseProtocolCachePolicy];
}
else {
{{classPrefix}}DebugLog(@"%@ cache disabled", resourcePath);
[request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];
}
if (hasHeaderParams){
for(NSString * key in [headerParams keyEnumerator]){
[request setValue:[headerParams valueForKey:key] forHTTPHeaderField:key];
}
}
[self.requestSerializer setValue:responseContentType forHTTPHeaderField:@"Accept"];
[self postProcessRequest:request];
NSNumber* requestId = [{{classPrefix}}ApiClient queueRequest];
if ([responseType isEqualToString:@"NSURL*"] || [responseType isEqualToString:@"NSURL"]) {
[self downloadOperationWithCompletionBlock:request requestId:requestId completionBlock:^(id data, NSError *error) {
completionBlock(data, error);
}];
}
else {
[self operationWithCompletionBlock:request requestId:requestId completionBlock:^(id data, NSError *error) {
NSError * serializationError;
id response = [self.responseDeserializer deserialize:data class:responseType error:&serializationError];
if(!response && !error){
error = serializationError;
}
completionBlock(response, error);
}];
}
return requestId;
}
//Added for easier override to modify request
-(void)postProcessRequest:(NSMutableURLRequest *)request {
// Always disable cookies!
[request setHTTPShouldHandleCookies:NO];
}
#pragma mark -
- (NSString*) pathWithQueryParamsToString:(NSString*) path
queryParams:(NSDictionary*) queryParams {
if(queryParams.count == 0) {
return path;
}
NSString * separator = nil;
NSUInteger counter = 0;
NSMutableString * requestUrl = [NSMutableString stringWithFormat:@"%@", path];
NSDictionary *separatorStyles = @{@"csv" : @",",
@"tsv" : @"\t",
@"pipes": @"|"
};
for(NSString * key in [queryParams keyEnumerator]){
if (counter == 0) {
separator = @"?";
} else {
separator = @"&";
}
id queryParam = [queryParams valueForKey:key];
if(!queryParam) {
continue;
}
NSString *safeKey = {{classPrefix}}PercentEscapedStringFromString(key);
if ([queryParam isKindOfClass:[NSString class]]){
[requestUrl appendString:[NSString stringWithFormat:@"%@%@=%@", separator, safeKey, {{classPrefix}}PercentEscapedStringFromString(queryParam)]];
} else if ([queryParam isKindOfClass:[{{classPrefix}}QueryParamCollection class]]){
{{classPrefix}}QueryParamCollection * coll = ({{classPrefix}}QueryParamCollection*) queryParam;
NSArray* values = [coll values];
NSString* format = [coll format];
if([format isEqualToString:@"multi"]) {
for(id obj in values) {
if (counter > 0) {
separator = @"&";
}
NSString * safeValue = {{classPrefix}}PercentEscapedStringFromString([NSString stringWithFormat:@"%@",obj]);
[requestUrl appendString:[NSString stringWithFormat:@"%@%@=%@", separator, safeKey, safeValue]];
counter += 1;
}
continue;
}
NSString * separatorStyle = separatorStyles[format];
NSString * safeValue = {{classPrefix}}PercentEscapedStringFromString([values componentsJoinedByString:separatorStyle]);
[requestUrl appendString:[NSString stringWithFormat:@"%@%@=%@", separator, safeKey, safeValue]];
} else {
NSString * safeValue = {{classPrefix}}PercentEscapedStringFromString([NSString stringWithFormat:@"%@",queryParam]);
[requestUrl appendString:[NSString stringWithFormat:@"%@%@=%@", separator, safeKey, safeValue]];
}
counter += 1;
}
return requestUrl;
}
/**
* Update header and query params based on authentication settings
*/
- (void) updateHeaderParams:(NSDictionary *__autoreleasing *)headers
queryParams:(NSDictionary *__autoreleasing *)querys
WithAuthSettings:(NSArray *)authSettings {
if ([authSettings count] == 0) {
return;
}
NSMutableDictionary *headersWithAuth = [NSMutableDictionary dictionaryWithDictionary:*headers];
NSMutableDictionary *querysWithAuth = [NSMutableDictionary dictionaryWithDictionary:*querys];
NSDictionary* configurationAuthSettings = [[self configuration] authSettings];
for (NSString *auth in authSettings) {
NSDictionary *authSetting = configurationAuthSettings[auth];
if(!authSetting) { // auth setting is set only if the key is non-empty
continue;
}
NSString *type = authSetting[@"in"];
NSString *key = authSetting[@"key"];
NSString *value = authSetting[@"value"];
if ([type isEqualToString:@"header"] && [key length] > 0 ) {
headersWithAuth[key] = value;
} else if ([type isEqualToString:@"query"] && [key length] != 0) {
querysWithAuth[key] = value;
}
}
*headers = [NSDictionary dictionaryWithDictionary:headersWithAuth];
*querys = [NSDictionary dictionaryWithDictionary:querysWithAuth];
}
- (AFSecurityPolicy *) customSecurityPolicy {
AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeNone];
{{classPrefix}}Configuration *config = [self configuration];
if (config.sslCaCert) {
NSData *certData = [NSData dataWithContentsOfFile:config.sslCaCert];
[securityPolicy setPinnedCertificates:@[certData]];
}
if (config.verifySSL) {
[securityPolicy setAllowInvalidCertificates:NO];
}
else {
[securityPolicy setAllowInvalidCertificates:YES];
[securityPolicy setValidatesDomainName:NO];
}
return securityPolicy;
}
- ({{classPrefix}}Configuration*) configuration {
return [{{classPrefix}}Configuration sharedConfig];
}
@end