Adding AFHTTPClientParameterEncoding @property to AFHTTPClient, which determines the method of encoding an NSDictionary of parameters for the body of an HTTP request

Minor refactoring of AFRestClient
This commit is contained in:
Mattt Thompson 2011-10-06 14:33:16 -05:00
parent 2d97154710
commit 6f20f84ef1
3 changed files with 98 additions and 23 deletions

View file

@ -25,6 +25,12 @@
@protocol AFMultipartFormData;
typedef enum {
AFFormURLParameterEncoding,
AFJSONParameterEncoding,
AFPropertyListParameterEncoding,
} AFHTTPClientParameterEncoding;
/**
`AFHTTPClient` objects encapsulates the common patterns of communicating with an application, webservice, or API. It encapsulates persistent information, like base URL, authorization credentials, and HTTP headers, and uses them to construct and manage the execution of HTTP request operations.
@ -49,6 +55,7 @@
@private
NSURL *_baseURL;
NSStringEncoding _stringEncoding;
AFHTTPClientParameterEncoding _parameterEncoding;
NSMutableArray *_registeredHTTPOperationClassNames;
NSMutableDictionary *_defaultHeaders;
NSOperationQueue *_operationQueue;
@ -68,6 +75,11 @@
*/
@property (nonatomic, assign) NSStringEncoding stringEncoding;
/**
*/
@property (nonatomic, assign) AFHTTPClientParameterEncoding parameterEncoding;
/**
The operation queue which manages operations enqueued by the HTTP client.
*/
@ -193,6 +205,9 @@
- (void)enqueueHTTPRequestOperationWithRequest:(NSURLRequest *)request
success:(void (^)(id object))success
failure:(void (^)(NSHTTPURLResponse *response, NSError *error))failure;
/**
*/
- (void)enqueueHTTPRequestOperation:(AFHTTPRequestOperation *)operation;
///---------------------------------
/// @name Cancelling HTTP Operations

View file

@ -22,6 +22,9 @@
#import "AFHTTPClient.h"
#import "AFJSONRequestOperation.h"
#import "JSONKit.h"
#include <Availability.h>
static NSString * const kAFMultipartFormLineDelimiter = @"\r\n"; // CRLF
static NSString * const kAFMultipartFormBoundary = @"Boundary+0xAbCdEfGbOuNdArY";
@ -40,6 +43,8 @@ static NSString * const kAFMultipartFormBoundary = @"Boundary+0xAbCdEfGbOuNdArY"
#pragma mark -
static NSUInteger const kAFHTTPClientDefaultMaxConcurrentOperationCount = 4;
static NSString * AFBase64EncodedStringFromString(NSString *string) {
NSData *data = [NSData dataWithBytes:[string UTF8String] length:[string length]];
NSUInteger length = [data length];
@ -69,10 +74,52 @@ static NSString * AFBase64EncodedStringFromString(NSString *string) {
return [[[NSString alloc] initWithData:mutableData encoding:NSASCIIStringEncoding] autorelease];
}
static NSString * AFURLEncodedStringFromStringWithEncoding(NSString *string, NSStringEncoding encoding) {
static NSString * AFURLEncodedStringFromString(NSString *string) {
static NSString * const kAFLegalCharactersToBeEscaped = @"?!@#$^&%*+,:;='\"`<>()[]{}/\\|~ ";
return [(NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)string, NULL, (CFStringRef)kAFLegalCharactersToBeEscaped, CFStringConvertNSStringEncodingToEncoding(encoding)) autorelease];
return [(NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)string, NULL, (CFStringRef)kAFLegalCharactersToBeEscaped, CFStringConvertNSStringEncodingToEncoding(NSUTF8StringEncoding)) autorelease];
}
static NSString * AFQueryStringFromParameters(NSDictionary *parameters) {
NSMutableArray *mutableParameterComponents = [NSMutableArray array];
for (id key in [parameters allKeys]) {
NSString *component = [NSString stringWithFormat:@"%@=%@", AFURLEncodedStringFromString([key description]), AFURLEncodedStringFromString([[parameters valueForKey:key] description])];
[mutableParameterComponents addObject:component];
}
return [mutableParameterComponents componentsJoinedByString:@"&"];
}
static NSString * AFJSONStringFromParameters(NSDictionary *parameters) {
NSString *JSONString = nil;
#if __IPHONE_OS_VERSION_MIN_REQUIRED > __IPHONE_4_3
if ([NSJSONSerialization class]) {
NSError *error = nil;
NSData *JSONData = [NSJSONSerialization dataWithJSONObject:parameters options:0 error:&error];
if (!error) {
JSONString = [[[NSString alloc] initWithData:JSONData encoding:NSUTF8StringEncoding] autorelease];
}
} else {
JSONString = [parameters JSONString];
}
#else
JSONString = [parameters JSONString];
#endif
return JSONString;
}
static NSString * AFPropertyListStringFromParameters(NSDictionary *parameters) {
NSString *propertyListString = nil;
NSError *error = nil;
NSData *propertyListData = [NSPropertyListSerialization dataWithPropertyList:parameters format:NSPropertyListXMLFormat_v1_0 options:0 error:&error];
if (!error) {
propertyListString = [[[NSString alloc] initWithData:propertyListData encoding:NSUTF8StringEncoding] autorelease];
}
return propertyListString;
}
@interface AFHTTPClient ()
@ -85,6 +132,7 @@ static NSString * AFURLEncodedStringFromStringWithEncoding(NSString *string, NSS
@implementation AFHTTPClient
@synthesize baseURL = _baseURL;
@synthesize stringEncoding = _stringEncoding;
@synthesize parameterEncoding = _parameterEncoding;
@synthesize registeredHTTPOperationClassNames = _registeredHTTPOperationClassNames;
@synthesize defaultHeaders = _defaultHeaders;
@synthesize operationQueue = _operationQueue;
@ -102,6 +150,7 @@ static NSString * AFURLEncodedStringFromStringWithEncoding(NSString *string, NSS
self.baseURL = url;
self.stringEncoding = NSUTF8StringEncoding;
self.parameterEncoding = AFJSONParameterEncoding;
self.registeredHTTPOperationClassNames = [NSMutableArray array];
@ -121,7 +170,7 @@ static NSString * AFURLEncodedStringFromStringWithEncoding(NSString *string, NSS
[self setDefaultHeader:@"User-Agent" value:[NSString stringWithFormat:@"%@/%@ (%@, %@ %@, %@, Scale/%f)", [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString *)kCFBundleIdentifierKey], [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString *)kCFBundleVersionKey], @"unknown", [[UIDevice currentDevice] systemName], [[UIDevice currentDevice] systemVersion], [[UIDevice currentDevice] model], ([[UIScreen mainScreen] respondsToSelector:@selector(scale)] ? [[UIScreen mainScreen] scale] : 1.0)]];
self.operationQueue = [[[NSOperationQueue alloc] init] autorelease];
[self.operationQueue setMaxConcurrentOperationCount:2];
[self.operationQueue setMaxConcurrentOperationCount:kAFHTTPClientDefaultMaxConcurrentOperationCount];
return self;
}
@ -177,30 +226,33 @@ static NSString * AFURLEncodedStringFromStringWithEncoding(NSString *string, NSS
path:(NSString *)path
parameters:(NSDictionary *)parameters
{
NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease];
NSMutableDictionary *headers = [NSMutableDictionary dictionaryWithDictionary:self.defaultHeaders];
NSURL *url = [NSURL URLWithString:path relativeToURL:self.baseURL];
NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] initWithURL:url] autorelease];
[request setHTTPMethod:method];
[request setAllHTTPHeaderFields:self.defaultHeaders];
if (parameters) {
NSMutableArray *mutableParameterComponents = [NSMutableArray array];
for (id key in [parameters allKeys]) {
NSString *component = [NSString stringWithFormat:@"%@=%@", AFURLEncodedStringFromStringWithEncoding([key description], self.stringEncoding), AFURLEncodedStringFromStringWithEncoding([[parameters valueForKey:key] description], self.stringEncoding)];
[mutableParameterComponents addObject:component];
}
NSString *queryString = [mutableParameterComponents componentsJoinedByString:@"&"];
if ([method isEqualToString:@"GET"]) {
url = [NSURL URLWithString:[[url absoluteString] stringByAppendingFormat:[path rangeOfString:@"?"].location == NSNotFound ? @"?%@" : @"&%@", queryString]];
url = [NSURL URLWithString:[[url absoluteString] stringByAppendingFormat:[path rangeOfString:@"?"].location == NSNotFound ? @"?%@" : @"&%@", AFQueryStringFromParameters(parameters)]];
[request setURL:url];
} else {
NSString *charset = (NSString *)CFStringConvertEncodingToIANACharSetName(CFStringConvertNSStringEncodingToEncoding(self.stringEncoding));
[headers setValue:[NSString stringWithFormat:@"application/x-www-form-urlencoded; charset=%@", charset] forKey:@"Content-Type"];
[request setHTTPBody:[queryString dataUsingEncoding:self.stringEncoding]];
switch (self.parameterEncoding) {
case AFFormURLParameterEncoding:;
[request setValue:[NSString stringWithFormat:@"application/x-www-form-urlencoded; charset=%@", charset] forHTTPHeaderField:@"Content-Type"];
[request setHTTPBody:[AFQueryStringFromParameters(parameters) dataUsingEncoding:self.stringEncoding]];
break;
case AFJSONParameterEncoding:;
[request setValue:[NSString stringWithFormat:@"application/json; charset=%@", charset] forHTTPHeaderField:@"Content-Type"];
[request setHTTPBody:[AFJSONStringFromParameters(parameters) dataUsingEncoding:self.stringEncoding]];
break;
case AFPropertyListParameterEncoding:;
[request setValue:[NSString stringWithFormat:@"application/x-plist; charset=%@", charset] forHTTPHeaderField:@"Content-Type"];
[request setHTTPBody:[AFPropertyListStringFromParameters(parameters) dataUsingEncoding:self.stringEncoding]];
break;
}
}
}
[request setURL:url];
[request setHTTPMethod:method];
[request setAllHTTPHeaderFields:headers];
return request;
}
@ -259,6 +311,14 @@ static NSString * AFURLEncodedStringFromStringWithEncoding(NSString *string, NSS
}
}
if (!operation) {
operation = [AFHTTPRequestOperation HTTPRequestOperationWithRequest:urlRequest success:success failure:failure];
}
[self enqueueHTTPRequestOperation:operation];
}
- (void)enqueueHTTPRequestOperation:(AFHTTPRequestOperation *)operation {
[self.operationQueue addOperation:operation];
}

View file

@ -236,10 +236,10 @@
F874B5C913E0AA6500B28E3E /* AFHTTPRequestOperation.m */,
F874B5D413E0AA6500B28E3E /* AFJSONRequestOperation.h */,
F874B5CC13E0AA6500B28E3E /* AFJSONRequestOperation.m */,
F8F4B16C143CD1410064C9E6 /* AFPropertyListRequestOperation.h */,
F8F4B16D143CD1410064C9E6 /* AFPropertyListRequestOperation.m */,
F8F4B17D143E07030064C9E6 /* AFXMLRequestOperation.h */,
F8F4B17E143E07030064C9E6 /* AFXMLRequestOperation.m */,
F8F4B16C143CD1410064C9E6 /* AFPropertyListRequestOperation.h */,
F8F4B16D143CD1410064C9E6 /* AFPropertyListRequestOperation.m */,
F8FBFA96142AA237001409DB /* AFHTTPClient.h */,
F8FBFA97142AA238001409DB /* AFHTTPClient.m */,
F874B5D313E0AA6500B28E3E /* AFImageRequestOperation.h */,