Skip to content
This repository has been archived by the owner on Jan 17, 2023. It is now read-only.

Commit

Permalink
Renaming AFMultipartFormDataProxy to AFMultipartFormData, in order to…
Browse files Browse the repository at this point in the history
… eliminate any confusion about it relating to a web proxy

Removing NSObject protocol from AFMultipartFormData protocol, since that's one of the points of abstracting away the interface

Refactoring mutlipart form appending methods to eliminate overlap, and be more useful in general

Updating documentation
  • Loading branch information
mattt committed Sep 26, 2011
1 parent f4f295f commit 945e196
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 50 deletions.
35 changes: 22 additions & 13 deletions AFNetworking/AFHTTPClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
#import <Foundation/Foundation.h>
#import "AFHTTPRequestOperation.h"

@protocol AFMultipartFormDataProxy;
@protocol AFMultipartFormData;

/**
`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.
Expand Down Expand Up @@ -133,21 +133,21 @@
path:(NSString *)path parameters:(NSDictionary *)parameters;

/**
Creates an `NSMutableURLRequest` object with the specified HTTP method and path, and constructs a `multipart/form-data` HTTP body, using the specified parameters and multipart form data block.
Creates an `NSMutableURLRequest` object with the specified HTTP method and path, and constructs a `multipart/form-data` HTTP body, using the specified parameters and multipart form data block. See http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4.2
@param method The HTTP method for the request. Must be either `POST`, `PUT`, or `DELETE`.
@param path The path to be appended to the HTTP client's base URL and used as the request URL.
@param parameters The parameters to be encoded and set in the request HTTP body.
@param block A block that takes a single argument and appends data to the HTTP body. The block argument is an object adopting the `AFMultipartFormDataProxy` protocol. This can be used to upload files, encode HTTP body as JSON or XML, or specify multiple values for the same parameter, as one might for array values.
@param block A block that takes a single argument and appends data to the HTTP body. The block argument is an object adopting the `AFMultipartFormData` protocol. This can be used to upload files, encode HTTP body as JSON or XML, or specify multiple values for the same parameter, as one might for array values.
@see AFMultipartFormDataProxy
@see AFMultipartFormData
@return An `NSMutableURLRequest` object
*/
- (NSMutableURLRequest *)multipartFormRequestWithMethod:(NSString *)method
path:(NSString *)path
parameters:(NSDictionary *)parameters
constructingBodyWithBlock:(void (^)(id <AFMultipartFormDataProxy>formData))block;
constructingBodyWithBlock:(void (^)(id <AFMultipartFormData> formData))block;


///--------------------------------
Expand Down Expand Up @@ -237,9 +237,9 @@
#pragma mark -

/**
The `AFMultipartFormDataProxy` protocol defines the methods supported by the parameter in the block argument of `multipartFormRequestWithMethod:path:parameters:constructingBodyWithBlock:`.
The `AFMultipartFormData` protocol defines the methods supported by the parameter in the block argument of `multipartFormRequestWithMethod:path:parameters:constructingBodyWithBlock:`.
*/
@protocol AFMultipartFormDataProxy <NSObject>
@protocol AFMultipartFormData

/**
Appends HTTP headers, followed by the encoded data and the multipart form boundary.
Expand All @@ -250,24 +250,33 @@
- (void)appendPartWithHeaders:(NSDictionary *)headers body:(NSData *)body;

/**
Appends the HTTP headers `Content-Disposition: form-data; name=#{name}"` and, if mimeType is specified, `Content-Type: #{mimeType}`, followed by the encoded data and the multipart form boundary.
Appends the HTTP headers `Content-Disposition: form-data; name=#{name}"`, followed by the encoded data and the multipart form boundary.
@param data The data to be encoded and appended to the form data.
@param mimeType The MIME type of the specified data. (For example, the MIME type for a JPEG image is image/jpeg.) For a list of valid MIME types, see http://www.iana.org/assignments/media-types/. If `nil`, the `Content-Type` header will be omitted.
@param name The name to be associated with the specified data. This parameter must not be `nil`.
*/
- (void)appendPartWithFormData:(NSData *)data mimeType:(NSString *)mimeType name:(NSString *)name;
- (void)appendPartWithFormData:(NSData *)data name:(NSString *)name;

/**
Appends the HTTP header `Content-Disposition: file; filename=#{generated filename}; name=#{name}"` and `Content-Type: #{mimeType}`, followed by the encoded file data and the multipart form boundary.
@param data The data to be encoded and appended to the form data.
@param mimeType The MIME type of the specified data. (For example, the MIME type for a JPEG image is image/jpeg.) For a list of valid MIME types, see http://www.iana.org/assignments/media-types/. This parameter must not be `nil`.
@param name The name to be associated with the specified data. This parameter must not be `nil`.
@discussion The filename associated with this data in the form will be automatically generated using the parameter name specified and a unique timestamp-based hash.
*/
- (void)appendPartWithFileData:(NSData *)data mimeType:(NSString *)mimeType name:(NSString *)name;

/**
Appends the HTTP header `Content-Disposition: file; filename=#{filename}"` and `Content-Type: #{mimeType}`, followed by the encoded file data and the multipart form boundary.
@param fileURL The URL for the local file to have its contents appended to the form data. This parameter must not be `nil`.
@param mimeType The MIME type of the specified data. (For example, the MIME type for a JPEG image is image/jpeg.) For a list of valid MIME types, see http://www.iana.org/assignments/media-types/. This parameter must not be `nil`.
@param fileName The filename to be associated with the file contents. This parameter must not be `nil`.
@param error If an error occurs, upon return contains an `NSError` object that describes the problem.
*/
- (void)appendPartWithFile:(NSURL *)fileURL mimeType:(NSString *)mimeType fileName:(NSString *)fileName;

- (void)appendPartWithFileData:(NSData *)data mimeType:(NSString *)mimeType name:(NSString *)name;
- (void)appendPartWithFile:(NSURL *)fileURL mimeType:(NSString *)mimeType fileName:(NSString *)fileName error:(NSError **)error;

/**
Appends encoded data to the form data.
Expand Down
58 changes: 21 additions & 37 deletions AFNetworking/AFHTTPClient.m
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
return [NSString stringWithFormat:@"%@--%@--", kAFMultipartFormLineDelimiter, kAFMultipartFormBoundary];
}

@interface AFMultipartFormDataProxy : NSObject <AFMultipartFormDataProxy> {
@interface AFMultipartFormData : NSObject <AFMultipartFormData> {
@private
NSStringEncoding _stringEncoding;
NSMutableData *_mutableData;
Expand Down Expand Up @@ -192,15 +192,15 @@ - (NSMutableURLRequest *)requestWithMethod:(NSString *)method path:(NSString *)p
- (NSMutableURLRequest *)multipartFormRequestWithMethod:(NSString *)method
path:(NSString *)path
parameters:(NSDictionary *)parameters
constructingBodyWithBlock:(void (^)(id <AFMultipartFormDataProxy>formData))block
constructingBodyWithBlock:(void (^)(id <AFMultipartFormData>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 AFMultipartFormDataProxy *formData = [[AFMultipartFormDataProxy alloc] initWithStringEncoding:self.stringEncoding];
__block AFMultipartFormData *formData = [[AFMultipartFormData alloc] initWithStringEncoding:self.stringEncoding];

id key = nil;
NSEnumerator *enumerator = [parameters keyEnumerator];
Expand All @@ -214,7 +214,7 @@ - (NSMutableURLRequest *)multipartFormRequestWithMethod:(NSString *)method
data = [[value description] dataUsingEncoding:self.stringEncoding];
}

[formData appendPartWithHeaders:[NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"form-data; name=\"%@\"", [key description]] forKey:@"Content-Disposition"] body:data];
[formData appendPartWithFormData:data name:[key description]];
}

if (block) {
Expand Down Expand Up @@ -272,15 +272,12 @@ - (void)deletePath:(NSString *)path parameters:(NSDictionary *)parameters succes

#pragma mark -

// multipart/form-data; see http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4.2
@interface AFMultipartFormDataProxy ()
@interface AFMultipartFormData ()
@property (readwrite, nonatomic, assign) NSStringEncoding stringEncoding;
@property (readwrite, nonatomic, retain) NSMutableData *mutableData;

- (void)appendBlankLine;
@end

@implementation AFMultipartFormDataProxy
@implementation AFMultipartFormData
@synthesize stringEncoding = _stringEncoding;
@synthesize mutableData = _mutableData;

Expand All @@ -307,48 +304,28 @@ - (NSData *)data {
return finalizedData;
}

#pragma mark - AFMultipartFormDataProxy
#pragma mark - AFMultipartFormData

- (void)appendPartWithHeaders:(NSDictionary *)headers body:(NSData *)body {

[self appendString:AFMultipartFormEncapsulationBoundary()];

for (NSString *field in [headers allKeys]) {
[self appendString:[NSString stringWithFormat:@"%@: %@%@", field, [headers valueForKey:field], kAFMultipartFormLineDelimiter]];
}

[self appendBlankLine];
[self appendString:kAFMultipartFormLineDelimiter];
[self appendData:body];
}

- (void)appendPartWithFormData:(NSData *)data mimeType:(NSString *)mimeType name:(NSString *)name {
- (void)appendPartWithFormData:(NSData *)data name:(NSString *)name {
NSMutableDictionary *mutableHeaders = [NSMutableDictionary dictionary];
[mutableHeaders setValue:[NSString stringWithFormat:@"form-data; name=\"%@\"", name] forKey:@"Content-Disposition"];
if (mimeType) {
[mutableHeaders setValue:mimeType forKey:@"Content-Type"];
}

[self appendPartWithHeaders:mutableHeaders body:data];
}

- (void)appendPartWithFile:(NSURL *)fileURL mimeType:(NSString *)mimeType fileName:(NSString *)fileName {
if (![fileURL isFileURL]) {
[NSException raise:@"Invalid fileURL value" format:@"%@ must be a valid file URL", fileURL];
return;
}

NSMutableDictionary *mutableHeaders = [NSMutableDictionary dictionary];
[mutableHeaders setValue:[NSString stringWithFormat:@"file; filename=\"%@\"", fileName] forKey:@"Content-Disposition"];
[mutableHeaders setValue:mimeType forKey:@"Content-Type"];

NSData *data = [NSData dataWithContentsOfFile:[fileURL absoluteString]];

[self appendPartWithHeaders:mutableHeaders body:data];
}

- (void)appendPartWithFileData:(NSData *)data mimeType:(NSString *)mimeType name:(NSString *)name {

NSString *fileName = [[NSString stringWithFormat:@"%d", [[NSDate date] hash]] stringByAppendingPathExtension:[mimeType lastPathComponent]];
NSString *fileName = [[NSString stringWithFormat:@"%@-%d", name, [[NSDate date] hash]] stringByAppendingPathExtension:[mimeType lastPathComponent]];

NSMutableDictionary *mutableHeaders = [NSMutableDictionary dictionary];
[mutableHeaders setValue:[NSString stringWithFormat:@"file; name=\"%@\"; filename=\"%@\"", name, fileName] forKey:@"Content-Disposition"];
Expand All @@ -357,6 +334,17 @@ - (void)appendPartWithFileData:(NSData *)data mimeType:(NSString *)mimeType name
[self appendPartWithHeaders:mutableHeaders body:data];
}

- (void)appendPartWithFile:(NSURL *)fileURL mimeType:(NSString *)mimeType fileName:(NSString *)fileName error:(NSError **)error {
NSData *data = [NSData dataWithContentsOfFile:[fileURL absoluteString] options:0 error:error];
if (data) {
NSMutableDictionary *mutableHeaders = [NSMutableDictionary dictionary];
[mutableHeaders setValue:[NSString stringWithFormat:@"file; filename=\"%@\"", fileName] forKey:@"Content-Disposition"];
[mutableHeaders setValue:mimeType forKey:@"Content-Type"];

[self appendPartWithHeaders:mutableHeaders body:data];
}
}

- (void)appendData:(NSData *)data {
[self.mutableData appendData:data];
}
Expand All @@ -365,8 +353,4 @@ - (void)appendString:(NSString *)string {
[self appendData:[string dataUsingEncoding:self.stringEncoding]];
}

- (void)appendBlankLine {
[self appendString:kAFMultipartFormLineDelimiter];
}

@end

0 comments on commit 945e196

Please sign in to comment.