Replacing NSMutableURLRequest category method with more flexible constructor in AFRestClient
Adding AFRestClient -multipartFormRequestWithMethod:path:parameters:constructingBodyWithBlock: Defining AFMultipartFormDataProxy protocol Replacing constant value for string encoding with @property with default of NSUTF8Encoding
This commit is contained in:
parent
ca02e02b11
commit
8b8605185b
5 changed files with 158 additions and 119 deletions
|
|
@ -23,7 +23,7 @@
|
|||
#import <Foundation/Foundation.h>
|
||||
#import "AFHTTPRequestOperation.h"
|
||||
|
||||
#import "NSMutableURLRequest+AFNetworking.h"
|
||||
@protocol AFMultipartFormDataProxy;
|
||||
|
||||
@interface AFRestClient : NSObject {
|
||||
@private
|
||||
|
|
@ -112,6 +112,12 @@
|
|||
- (NSMutableURLRequest *)requestWithMethod:(NSString *)method
|
||||
path:(NSString *)path parameters:(NSDictionary *)parameters;
|
||||
|
||||
- (NSMutableURLRequest *)multipartFormRequestWithMethod:(NSString *)method
|
||||
path:(NSString *)path
|
||||
parameters:(NSDictionary *)parameters
|
||||
constructingBodyWithBlock:(void (^)(id <AFMultipartFormDataProxy>formData))block;
|
||||
|
||||
|
||||
///--------------------------------
|
||||
/// @name Enqueuing HTTP Operations
|
||||
///--------------------------------
|
||||
|
|
@ -132,9 +138,9 @@
|
|||
///---------------------------
|
||||
/// @name Making HTTP Requests
|
||||
///---------------------------
|
||||
- (void)getPath:(NSString *)path
|
||||
parameters:(NSDictionary *)parameters
|
||||
success:(void (^)(id response))success
|
||||
- (void)getPath:(NSString *)path
|
||||
parameters:(NSDictionary *)parameters
|
||||
success:(void (^)(id response))success
|
||||
failure:(void (^)(NSError *error))failure;
|
||||
|
||||
- (void)postPath:(NSString *)path
|
||||
|
|
@ -152,3 +158,13 @@
|
|||
success:(void (^)(id response))success
|
||||
failure:(void (^)(NSError *error))failure;
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
|
||||
@protocol AFMultipartFormDataProxy <NSObject>
|
||||
- (void)appendPartWithHeaders:(NSDictionary *)headers body:(NSData *)body;
|
||||
- (void)appendPartWithFormData:(NSData *)data name:(NSString *)name;
|
||||
- (void)appendPartWithFile:(NSURL *)fileURL fileName:(NSString *)fileNameOrNil;
|
||||
- (void)appendData:(NSData *)data;
|
||||
- (void)appendString:(NSString *)string;
|
||||
@end
|
||||
|
|
|
|||
|
|
@ -23,6 +23,31 @@
|
|||
#import "AFRestClient.h"
|
||||
#import "AFJSONRequestOperation.h"
|
||||
|
||||
static NSString * const kAFMultipartFormLineDelimiter = @"\r\n"; // CRLF
|
||||
static NSString * const kAFMultipartFormBoundary = @"Boundary+0xAbCdEfGbOuNdArY";
|
||||
|
||||
static NSString * AFMultipartFormEncapsulationBoundary() {
|
||||
return [NSString stringWithFormat:@"--%@", kAFMultipartFormBoundary];
|
||||
}
|
||||
|
||||
static NSString * AFMultipartFormFinalBoundary() {
|
||||
return [NSString stringWithFormat:@"--%@--", kAFMultipartFormBoundary];
|
||||
}
|
||||
|
||||
@interface AFMutableMultipartFormData : NSObject <AFMultipartFormDataProxy> {
|
||||
@private
|
||||
NSStringEncoding _stringEncoding;
|
||||
NSMutableArray *_lines;
|
||||
}
|
||||
|
||||
- (id)initWithStringEncoding:(NSStringEncoding)encoding;
|
||||
|
||||
- (NSData *)data;
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
|
||||
static NSString * AFBase64EncodedStringFromString(NSString *string) {
|
||||
NSData *data = [NSData dataWithBytes:[string UTF8String] length:[string length]];
|
||||
NSUInteger length = [data length];
|
||||
|
|
@ -161,6 +186,42 @@ static NSString * AFURLEncodedStringFromStringWithEncoding(NSString *string, NSS
|
|||
return request;
|
||||
}
|
||||
|
||||
- (NSMutableURLRequest *)multipartFormRequestWithMethod:(NSString *)method
|
||||
path:(NSString *)path
|
||||
parameters:(NSDictionary *)parameters
|
||||
constructingBodyWithBlock:(void (^)(id <AFMultipartFormDataProxy>formData))block
|
||||
{
|
||||
if (!([method isEqualToString:@"POST"] || [method isEqualToString:@"PUT"] || [method isEqualToString:@"DELETE"])) {
|
||||
[NSException raise:@"Invalid HTTP Method" format:@"%@ is not supported for multipart form requests; must be either POST, PUT, or DELETE", method];
|
||||
return nil;
|
||||
}
|
||||
|
||||
NSMutableURLRequest *request = [self requestWithMethod:method path:path parameters:nil];
|
||||
__block AFMutableMultipartFormData *formData = [[AFMutableMultipartFormData alloc] init];
|
||||
|
||||
id key = nil;
|
||||
NSEnumerator *enumerator = [parameters keyEnumerator];
|
||||
while ((key = [enumerator nextObject])) {
|
||||
id value = [parameters valueForKey:key];
|
||||
if (![value isKindOfClass:[NSData class]]) {
|
||||
value = [value description];
|
||||
}
|
||||
|
||||
[formData appendPartWithFormData:[value dataUsingEncoding:self.stringEncoding] name:[key description]];
|
||||
}
|
||||
|
||||
if (block) {
|
||||
block(formData);
|
||||
}
|
||||
|
||||
[request setValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@", kAFMultipartFormBoundary] forHTTPHeaderField:@"Content-Type"];
|
||||
[request setHTTPBody:[formData data]];
|
||||
|
||||
[formData autorelease];
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
- (void)enqueueHTTPOperation:(AFHTTPRequestOperation *)operation {
|
||||
[self.operationQueue addOperation:operation];
|
||||
}
|
||||
|
|
@ -209,3 +270,80 @@ static NSString * AFURLEncodedStringFromStringWithEncoding(NSString *string, NSS
|
|||
}
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
|
||||
// multipart/form-data; see http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4.2
|
||||
@interface AFMutableMultipartFormData ()
|
||||
@property (readwrite, nonatomic, assign) NSStringEncoding stringEncoding;
|
||||
@property (readwrite, nonatomic, retain) NSMutableArray *lines;
|
||||
|
||||
- (void)appendBlankLine;
|
||||
@end
|
||||
|
||||
@implementation AFMutableMultipartFormData
|
||||
@synthesize stringEncoding = _stringEncoding;
|
||||
@synthesize lines = _lines;
|
||||
|
||||
- (id)initWithStringEncoding:(NSStringEncoding)encoding {
|
||||
self = [super init];
|
||||
if (!self) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
self.stringEncoding = encoding;
|
||||
self.lines = [NSMutableArray array];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
[_lines release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (NSData *)data {
|
||||
NSLog(@"DATA: %@", [[self.lines componentsJoinedByString:kAFMultipartFormLineDelimiter] stringByAppendingString:AFMultipartFormFinalBoundary()]);
|
||||
|
||||
return [[[[self.lines componentsJoinedByString:kAFMultipartFormLineDelimiter] stringByAppendingString:AFMultipartFormFinalBoundary()] stringByAppendingString:kAFMultipartFormLineDelimiter] dataUsingEncoding:self.stringEncoding];
|
||||
}
|
||||
|
||||
#pragma mark - AFMultipartFormDataProxy
|
||||
|
||||
- (void)appendPartWithHeaders:(NSDictionary *)headers body:(NSData *)body {
|
||||
for (NSString *field in [headers allKeys]) {
|
||||
[self appendString:[NSString stringWithFormat:@"%@: %@", field, [headers valueForKey:field]]];
|
||||
}
|
||||
|
||||
[self appendBlankLine];
|
||||
[self appendData:body];
|
||||
}
|
||||
|
||||
- (void)appendPartWithFormData:(NSData *)data name:(NSString *)name {
|
||||
[self appendPartWithHeaders:[NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"form-data; name=\"%@\"", name] forKey:@"Content-Disposition"] body:data];
|
||||
}
|
||||
|
||||
- (void)appendPartWithFile:(NSURL *)fileURL fileName:(NSString *)fileNameOrNil {
|
||||
if (![fileURL isFileURL]) {
|
||||
[NSException raise:@"Invalid fileURL value" format:@"%@ must be a valid file URL", fileURL];
|
||||
return;
|
||||
}
|
||||
|
||||
NSData *data = [NSData dataWithContentsOfFile:[fileURL absoluteString]];
|
||||
NSString *fileName = fileNameOrNil ? fileNameOrNil : [[fileURL lastPathComponent] stringByAppendingPathExtension:[fileURL pathExtension]];
|
||||
[self appendPartWithHeaders:[NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"file; filename=\"%@\"", fileName] forKey:@"Content-Disposition"] body:data];
|
||||
}
|
||||
|
||||
- (void)appendData:(NSData *)data {
|
||||
[self appendString:[[[NSString alloc] initWithData:data encoding:self.stringEncoding] autorelease]];
|
||||
}
|
||||
|
||||
- (void)appendString:(NSString *)string {
|
||||
[self.lines addObject:string];
|
||||
}
|
||||
|
||||
- (void)appendBlankLine {
|
||||
[self appendString:@""];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
|||
|
|
@ -1,33 +0,0 @@
|
|||
// NSMutableURLRequest+AFNetworking.h
|
||||
//
|
||||
// Copyright (c) 2011 Gowalla (http://gowalla.com/)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface NSMutableURLRequest (AFNetworking)
|
||||
|
||||
- (void)setHTTPBodyWithData:(NSData *)data
|
||||
mimeType:(NSString *)mimeType
|
||||
forParameterNamed:(NSString *)parameterName
|
||||
parameters:(NSDictionary *)parameters
|
||||
useGzipCompression:(BOOL)useGzipCompression;
|
||||
|
||||
@end
|
||||
|
|
@ -1,76 +0,0 @@
|
|||
// NSMutableURLRequest+AFNetworking.m
|
||||
//
|
||||
// Copyright (c) 2011 Gowalla (http://gowalla.com/)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import "NSMutableURLRequest+AFNetworking.h"
|
||||
#import "NSData+AFNetworking.h"
|
||||
|
||||
@implementation NSMutableURLRequest (AFNetworking)
|
||||
|
||||
- (void)setHTTPBodyWithData:(NSData *)data
|
||||
mimeType:(NSString *)mimeType
|
||||
forParameterNamed:(NSString *)parameterName
|
||||
parameters:(NSDictionary *)parameters
|
||||
useGzipCompression:(BOOL)useGzipCompression
|
||||
{
|
||||
if ([[self HTTPMethod] isEqualToString:@"GET"]) {
|
||||
[self setHTTPMethod:@"POST"];
|
||||
}
|
||||
|
||||
NSString *filename = [[NSString stringWithFormat:@"%d", [[NSDate date] hash]] stringByAppendingPathExtension:[mimeType lastPathComponent]];
|
||||
|
||||
static NSString * const boundary = @"----Boundary+0xAbCdEfGbOuNdArY";
|
||||
[self setValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary] forHTTPHeaderField:@"Content-Type"];
|
||||
|
||||
NSMutableData *mutableData = [NSMutableData data];
|
||||
[mutableData appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
|
||||
|
||||
id key;
|
||||
NSEnumerator *enumerator = [parameters keyEnumerator];
|
||||
while ((key = [enumerator nextObject])) {
|
||||
[mutableData appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n", key] dataUsingEncoding:NSUTF8StringEncoding]];
|
||||
[mutableData appendData:[[NSString stringWithFormat:@"%@", [parameters valueForKey:key]] dataUsingEncoding:NSUTF8StringEncoding]];
|
||||
[mutableData appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
|
||||
}
|
||||
|
||||
[mutableData appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"%@\"", parameterName, filename, nil] dataUsingEncoding:NSUTF8StringEncoding]];
|
||||
[mutableData appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
|
||||
[mutableData appendData:[[NSString stringWithFormat:@"Content-Type: %@", mimeType] dataUsingEncoding:NSUTF8StringEncoding]];
|
||||
[mutableData appendData:[@"\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
|
||||
[mutableData appendData:data];
|
||||
[mutableData appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
|
||||
|
||||
if (useGzipCompression) {
|
||||
NSError *error = nil;
|
||||
NSData *compressedData = [mutableData dataByGZipCompressingWithError:&error];
|
||||
|
||||
if (!error && compressedData) {
|
||||
[self setHTTPBody:compressedData];
|
||||
|
||||
// Content-Encoding HTTP Header; see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.11
|
||||
[self setValue:@"gzip" forHTTPHeaderField:@"Content-Encoding"];
|
||||
}
|
||||
} else {
|
||||
[self setHTTPBody:mutableData];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
@ -7,7 +7,6 @@
|
|||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
F85CE2DC13EC4A4200BFAE01 /* NSMutableURLRequest+AFNetworking.m in Sources */ = {isa = PBXBuildFile; fileRef = F85CE2DB13EC4A4200BFAE01 /* NSMutableURLRequest+AFNetworking.m */; };
|
||||
F874B5D913E0AA6500B28E3E /* AFHTTPRequestOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = F874B5C913E0AA6500B28E3E /* AFHTTPRequestOperation.m */; };
|
||||
F874B5DA13E0AA6500B28E3E /* AFImageCache.m in Sources */ = {isa = PBXBuildFile; fileRef = F874B5CA13E0AA6500B28E3E /* AFImageCache.m */; };
|
||||
F874B5DB13E0AA6500B28E3E /* AFImageRequestOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = F874B5CB13E0AA6500B28E3E /* AFImageRequestOperation.m */; };
|
||||
|
|
@ -34,8 +33,6 @@
|
|||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
F85CE2DA13EC4A4200BFAE01 /* NSMutableURLRequest+AFNetworking.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSMutableURLRequest+AFNetworking.h"; path = "../AFNetworking/NSMutableURLRequest+AFNetworking.h"; sourceTree = "<group>"; };
|
||||
F85CE2DB13EC4A4200BFAE01 /* NSMutableURLRequest+AFNetworking.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSMutableURLRequest+AFNetworking.m"; path = "../AFNetworking/NSMutableURLRequest+AFNetworking.m"; sourceTree = "<group>"; };
|
||||
F874B5C913E0AA6500B28E3E /* AFHTTPRequestOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AFHTTPRequestOperation.m; path = ../AFNetworking/AFHTTPRequestOperation.m; sourceTree = "<group>"; };
|
||||
F874B5CA13E0AA6500B28E3E /* AFImageCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AFImageCache.m; path = ../AFNetworking/AFImageCache.m; sourceTree = "<group>"; };
|
||||
F874B5CB13E0AA6500B28E3E /* AFImageRequestOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AFImageRequestOperation.m; path = ../AFNetworking/AFImageRequestOperation.m; sourceTree = "<group>"; };
|
||||
|
|
@ -101,8 +98,6 @@
|
|||
F85CE2D613EC47BC00BFAE01 /* Categories */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F85CE2DA13EC4A4200BFAE01 /* NSMutableURLRequest+AFNetworking.h */,
|
||||
F85CE2DB13EC4A4200BFAE01 /* NSMutableURLRequest+AFNetworking.m */,
|
||||
F874B5D713E0AA6500B28E3E /* UIImage+AFNetworking.h */,
|
||||
F874B5CF13E0AA6500B28E3E /* UIImage+AFNetworking.m */,
|
||||
F874B5D813E0AA6500B28E3E /* UIImageView+AFNetworking.h */,
|
||||
|
|
@ -348,7 +343,6 @@
|
|||
F874B5DE13E0AA6500B28E3E /* AFRestClient.m in Sources */,
|
||||
F874B5DF13E0AA6500B28E3E /* UIImage+AFNetworking.m in Sources */,
|
||||
F874B5E013E0AA6500B28E3E /* UIImageView+AFNetworking.m in Sources */,
|
||||
F85CE2DC13EC4A4200BFAE01 /* NSMutableURLRequest+AFNetworking.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue