From 4647907ea0794219eefd4e4d7f91a2909266de18 Mon Sep 17 00:00:00 2001 From: Stephan Diederich Date: Thu, 15 Aug 2013 22:29:38 +0200 Subject: [PATCH] allow to create URL-requests with parameters --- Classes/BITAuthenticator.m | 55 +++++++++++++++++++++++++++--- Classes/BITAuthenticator_Private.h | 17 ++++++++- 2 files changed, 67 insertions(+), 5 deletions(-) diff --git a/Classes/BITAuthenticator.m b/Classes/BITAuthenticator.m index 732ab65623..d5f8d54b89 100644 --- a/Classes/BITAuthenticator.m +++ b/Classes/BITAuthenticator.m @@ -308,18 +308,58 @@ static NSString* const kBITAuthenticatorLastAuthenticatedVersionKey = @"BITAuthe #pragma mark - Networking - (NSMutableURLRequest *) requestWithMethod:(NSString*) method - path:(NSString *) path { + path:(NSString *) path + parameters:(NSDictionary *)params { NSParameterAssert(self.serverURL); NSParameterAssert(method); + NSParameterAssert(params == nil || [method isEqualToString:@"POST"] || [method isEqualToString:@"GET"]); path = path ? : @""; NSURL *endpoint = [[NSURL URLWithString:self.serverURL] URLByAppendingPathComponent:path]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:endpoint]; request.HTTPMethod = method; + if (params) { + if ([method isEqualToString:@"GET"]) { + NSString *absoluteURLString = [endpoint absoluteString]; + //either path already has parameters, or not + NSString *appenderFormat = [path rangeOfString:@"?"].location == NSNotFound ? @"?%@" : @"&%@"; + + endpoint = [NSURL URLWithString:[absoluteURLString stringByAppendingFormat:appenderFormat, + [self.class queryStringFromParameters:params withEncoding:NSUTF8StringEncoding]]]; + [request setURL:endpoint]; + } else { + //TODO: this is crap. Boundary must be the same as the one in appendData + //unify this! + NSString *boundary = @"----FOO"; + NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary]; + [request setValue:contentType forHTTPHeaderField:@"Content-type"]; + + NSMutableData *postBody = [NSMutableData data]; + [params enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSString *value, BOOL *stop) { + [postBody appendData:[self appendPostValue:value forKey:key]]; + }]; + + [postBody appendData:[[NSString stringWithFormat:@"--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]]; + + [request setHTTPBody:postBody]; + } + } + return request; } ++ (NSString *) queryStringFromParameters:(NSDictionary *) params withEncoding:(NSStringEncoding) encoding { + NSMutableString *queryString = [NSMutableString new]; + [params enumerateKeysAndObjectsUsingBlock:^(NSString* key, NSString* value, BOOL *stop) { + NSAssert([key isKindOfClass:[NSString class]], @"Query parameters can only be string-string pairs"); + NSAssert([value isKindOfClass:[NSString class]], @"Query parameters can only be string-string pairs"); + + [queryString appendFormat:queryString.length ? @"&%@=%@" : @"%@=%@", key, value]; + }]; + return queryString; +} + - (BITHTTPOperation*) operationWithURLRequest:(NSURLRequest*) request completion:(BITNetworkCompletionBlock) completion { BITHTTPOperation *operation = [BITHTTPOperation operationWithRequest:request @@ -329,8 +369,15 @@ static NSString* const kBITAuthenticatorLastAuthenticatedVersionKey = @"BITAuthe return operation; } -- (void)getPath:(NSString *)path completion:(BITNetworkCompletionBlock)completion { - NSURLRequest *request = [self requestWithMethod:@"GET" path:path]; +- (void)getPath:(NSString *)path parameters:(NSDictionary *)params completion:(BITNetworkCompletionBlock)completion { + NSURLRequest *request = [self requestWithMethod:@"GET" path:path parameters:params]; + BITHTTPOperation *op = [self operationWithURLRequest:request + completion:completion]; + [self enqeueHTTPOperation:op]; +} + +- (void)postPath:(NSString *)path parameters:(NSDictionary *)params completion:(BITNetworkCompletionBlock)completion { + NSURLRequest *request = [self requestWithMethod:@"POST" path:path parameters:params]; BITHTTPOperation *op = [self operationWithURLRequest:request completion:completion]; [self enqeueHTTPOperation:op]; @@ -354,7 +401,7 @@ static NSString* const kBITAuthenticatorLastAuthenticatedVersionKey = @"BITAuthe BOOL matchedPath = YES; if(path) { //method is not interesting here, we' just creating it to get the URL - NSURL *url = [self requestWithMethod:@"GET" path:path].URL; + NSURL *url = [self requestWithMethod:@"GET" path:path parameters:nil].URL; matchedPath = [request.URL isEqual:url]; } diff --git a/Classes/BITAuthenticator_Private.h b/Classes/BITAuthenticator_Private.h index 8be28d7fe9..15f7cc8302 100644 --- a/Classes/BITAuthenticator_Private.h +++ b/Classes/BITAuthenticator_Private.h @@ -56,12 +56,14 @@ * the internally stored baseURL. * * @param method the HTTPMethod to check, must not be nil + * @param params parameters for the request (only supported for GET and POST for now) * @param path path to append to baseURL. can be nil in which case "/" is appended * * @return an NSMutableURLRequest for further configuration */ - (NSMutableURLRequest *) requestWithMethod:(NSString*) method - path:(NSString *) path; + path:(NSString *) path + parameters:(NSDictionary *) params; /** * Creates an operation for the given NSURLRequest * @@ -77,12 +79,25 @@ * Creates an operation for the given path, and enqueues it * * @param path the request path to check + * @param params parameters for the request * @param completion completionBlock that is called once the operation finished * */ - (void) getPath:(NSString*) path + parameters:(NSDictionary *) params completion:(BITNetworkCompletionBlock) completion; +/** + * Creates an operation for the given path, and enqueues it + * + * @param path the request path to check + * @param params parameters for the request + * @param completion completionBlock that is called once the operation finished + * + */ +- (void) postPath:(NSString*) path + parameters:(NSDictionary *) params + completion:(BITNetworkCompletionBlock) completion; /** * adds the given operation to the internal queue *