Skip to content

Instantly share code, notes, and snippets.

@sclark39
Created February 28, 2017 14:26
Show Gist options
  • Save sclark39/6b03820eba8a26ace6bb97fbccd121a9 to your computer and use it in GitHub Desktop.
Save sclark39/6b03820eba8a26ace6bb97fbccd121a9 to your computer and use it in GitHub Desktop.
/*
Copyright 2010-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License").
You may not use this file except in compliance with the License.
A copy of the License is located at
http://aws.amazon.com/apache2.0
or in the "license" file accompanying this file. This file is distributed
on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
express or implied. See the License for the specific language governing
permissions and limitations under the License.
*/
#import "WOMAPIGatewayClient.h"
#import <AWSCore/AWSCore.h>
#import <AWSCore/AWSSignature.h>
#import <AWSCore/AWSSynchronizedMutableDictionary.h>
NSString *const AWSAPIGatewayErrorDomain = @"com.amazonaws.AWSAPIGatewayErrorDomain";
NSString *const AWSAPIGatewayErrorHTTPBodyKey = @"HTTPBody";
NSString *const AWSAPIGatewayErrorHTTPHeaderFieldsKey = @"HTTPHeaderFields";
static NSString *const AWSAPIGatewayAPIKeyHeader = @"x-api-key";
static NSString *const AWSAPIGatewaySDKVersion = @"2.5.1";
static NSString *const AWSAPIGatewayEndpoint = @"https://........................";
static int defaultChunkSize = 1024;
@interface AWSAPIGatewayClient()
// Networking
@property (nonatomic, strong) NSURLSession *session;
// For requests
@property (nonatomic, strong) NSURL *baseURL;
// For responses
@property (nonatomic, strong) NSDictionary *HTTPHeaderFields;
@property (nonatomic, assign) NSInteger HTTPStatusCode;
- (NSURL *)requestURL:(NSString *)URLString query:(NSDictionary *)query URLPathComponentsDictionary:(NSDictionary * _Nullable)URLPathComponentsDictionary;
@end
@interface WOMAPIGatewayClient()
@property (nonatomic, strong) AWSServiceConfiguration *configuration;
@end
@interface AWSServiceConfiguration()
@property (nonatomic, strong) AWSEndpoint *endpoint;
@end
@implementation WOMAPIGatewayClient
static NSString *const AWSInfoClientKey = @"WOMAPIGatewayClient";
@synthesize configuration = _configuration;
static AWSSynchronizedMutableDictionary *_serviceClients = nil;
+ (instancetype)defaultClient {
AWSServiceConfiguration *serviceConfiguration = nil;
AWSServiceInfo *serviceInfo = [[AWSInfo defaultAWSInfo] defaultServiceInfo:AWSInfoClientKey];
if (serviceInfo) {
serviceConfiguration = [[AWSServiceConfiguration alloc] initWithRegion:serviceInfo.region
credentialsProvider:serviceInfo.cognitoCredentialsProvider];
} else if ([AWSServiceManager defaultServiceManager].defaultServiceConfiguration) {
serviceConfiguration = AWSServiceManager.defaultServiceManager.defaultServiceConfiguration;
} else {
serviceConfiguration = [[AWSServiceConfiguration alloc] initWithRegion:AWSRegionUnknown
credentialsProvider:nil];
}
static WOMAPIGatewayClient *_defaultClient = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_defaultClient = [[WOMAPIGatewayClient alloc] initWithConfiguration:serviceConfiguration];
});
return _defaultClient;
}
+ (void)registerClientWithConfiguration:(AWSServiceConfiguration *)configuration forKey:(NSString *)key {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_serviceClients = [AWSSynchronizedMutableDictionary new];
});
[_serviceClients setObject:[[WOMAPIGatewayClient alloc] initWithConfiguration:configuration]
forKey:key];
}
+ (instancetype)clientForKey:(NSString *)key {
@synchronized(self) {
WOMAPIGatewayClient *serviceClient = [_serviceClients objectForKey:key];
if (serviceClient) {
return serviceClient;
}
AWSServiceInfo *serviceInfo = [[AWSInfo defaultAWSInfo] serviceInfo:AWSInfoClientKey
forKey:key];
if (serviceInfo) {
AWSServiceConfiguration *serviceConfiguration = [[AWSServiceConfiguration alloc] initWithRegion:serviceInfo.region
credentialsProvider:serviceInfo.cognitoCredentialsProvider];
[WOMAPIGatewayClient registerClientWithConfiguration:serviceConfiguration
forKey:key];
}
return [_serviceClients objectForKey:key];
}
}
+ (void)removeClientForKey:(NSString *)key {
[_serviceClients removeObjectForKey:key];
}
- (instancetype)init {
@throw [NSException exceptionWithName:NSInternalInconsistencyException
reason:@"`- init` is not a valid initializer. Use `+ defaultClient` or `+ clientForKey:` instead."
userInfo:nil];
return nil;
}
- (instancetype)initWithConfiguration:(AWSServiceConfiguration *)configuration {
if (self = [super init]) {
_configuration = [configuration copy];
NSString *URLString = AWSAPIGatewayEndpoint
if ([URLString hasSuffix:@"/"]) {
URLString = [URLString substringToIndex:[URLString length] - 1];
}
_configuration.endpoint = [[AWSEndpoint alloc] initWithRegion:_configuration.regionType
service:AWSServiceAPIGateway
URL:[NSURL URLWithString:URLString]];
AWSSignatureV4Signer *signer = [[AWSSignatureV4Signer alloc] initWithCredentialsProvider:_configuration.credentialsProvider
endpoint:_configuration.endpoint];
_configuration.baseURL = _configuration.endpoint.URL;
_configuration.requestInterceptors = @[[AWSNetworkingRequestInterceptor new], signer];
}
return self;
}
- (AWSTask *)invokeHTTPRequest:(NSString *)HTTPMethod
URLString:(NSString *)URLString
pathParameters:(NSDictionary * _Nullable)pathParameters
queryParameters:(NSDictionary *)queryParameters
headerParameters:(NSDictionary *)headerParameters
body:(NSDictionary * _Nullable)body
{
NSURL *URL = [self requestURL:URLString query:queryParameters URLPathComponentsDictionary:pathParameters];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL];
request.HTTPMethod = HTTPMethod;
request.allHTTPHeaderFields = headerParameters;
if (self.APIKey) {
[request addValue:self.APIKey forHTTPHeaderField:AWSAPIGatewayAPIKeyHeader];
}
NSError *error = nil;
if (body != nil) {
request.HTTPBody = [NSJSONSerialization dataWithJSONObject:body
options:0
error:&error];
if (!request.HTTPBody) {
AWSLogError(@"Failed to serialize a request body. %@", error);
}
}
// Refreshes credentials if necessary
AWSTask *task = [AWSTask taskWithResult:nil];
task = [task continueWithSuccessBlock:^id(AWSTask *task) {
id signer = [self.configuration.requestInterceptors lastObject];
if (signer) {
if ([signer respondsToSelector:@selector(credentialsProvider)]) {
id<AWSCredentialsProvider> credentialsProvider = [signer performSelector:@selector(credentialsProvider)];
return [credentialsProvider credentials];
}
}
return nil;
}];
// Signs the request
for (id<AWSNetworkingRequestInterceptor> interceptor in self.configuration.requestInterceptors) {
task = [task continueWithSuccessBlock:^id(AWSTask *task) {
return [interceptor interceptRequest:request];
}];
}
return [task continueWithSuccessBlock:^id(AWSTask *task) {
AWSTaskCompletionSource *completionSource = [AWSTaskCompletionSource new];
void (^completionHandler)(NSData *data, NSURLResponse *response, NSError *error) = ^(NSData *data, NSURLResponse *response, NSError *error) {
// Networking errors
if (error) {
[completionSource setError:error];
return;
}
// Serializes the HTTP body
id JSONObject = nil;
if (data && [data length] > 0) {
JSONObject = [NSJSONSerialization JSONObjectWithData:data
options:NSJSONReadingAllowFragments
error:&error];
if (!JSONObject) {
NSString *bodyString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
if ([bodyString length] > 0) {
AWSLogError(@"The body is not in JSON format. Body: %@\nError: %@", bodyString, error);
}
[completionSource setError:error];
return;
}
}
// Handles developer defined errors
NSHTTPURLResponse *HTTPResponse = (NSHTTPURLResponse *)response;
NSDictionary *HTTPHeaderFields = HTTPResponse.allHeaderFields;
NSInteger HTTPStatusCode = HTTPResponse.statusCode;
if (HTTPStatusCode/100 == 4 || HTTPStatusCode/100 == 5) {
NSMutableDictionary *userInfo = [NSMutableDictionary new];
if (JSONObject) {
userInfo[AWSAPIGatewayErrorHTTPBodyKey] = JSONObject;
}
if (HTTPHeaderFields) {
userInfo[AWSAPIGatewayErrorHTTPHeaderFieldsKey] = HTTPHeaderFields;
}
if (HTTPStatusCode/100 == 4) {
NSError *clientError = [NSError errorWithDomain:AWSAPIGatewayErrorDomain
code:AWSAPIGatewayErrorTypeClient
userInfo:userInfo];
[completionSource setError:clientError];
}
if (HTTPStatusCode/100 == 5) {
NSError *clientError = [NSError errorWithDomain:AWSAPIGatewayErrorDomain
code:AWSAPIGatewayErrorTypeService
userInfo:userInfo];
[completionSource setError:clientError];
}
return;
}
// Maps a serialized JSON object to an Objective-C object
if (JSONObject)
{
[completionSource setResult:JSONObject];
} else {
[completionSource setResult:nil];
}
};
NSURLSessionDataTask *sessionTask = [self.session dataTaskWithRequest:request
completionHandler:completionHandler];
[sessionTask resume];
return completionSource.task;
}];
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment