Last active
February 20, 2017 21:13
-
-
Save tobitech/1d1db93bf14cf7989c3267c09e6cd035 to your computer and use it in GitHub Desktop.
Multipart form for uploading data over HTTP
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import <Foundation/Foundation.h> | |
#import <UIKit/UIKit.h> | |
/** | |
* Represents a multi-part for uploading data over HTTP. | |
*/ | |
@interface CFMultipartForm : NSObject | |
/** | |
* Add a simple form name-value pair | |
*/ | |
- (void)addFormValue:(NSString *)value forName:(NSString *)name; | |
/** | |
* Add PNG image data | |
*/ | |
- (void)addPNGImage:(UIImage *)image forName:(NSString *)name; | |
/** | |
* Add JPEG image data | |
*/ | |
- (void)addJPEGImage:(UIImage *)image forName:(NSString *)name; | |
/** | |
* Add Video data | |
*/ | |
- (void)addVideo:(NSData *)videoData forName:(NSString *)name; | |
/** | |
* Add file data with the given content-type | |
*/ | |
- (void)addFileAtURL:(NSURL *)URL contentType:(NSString *)contentType fileName:(NSString *)fileName forName:(NSString *)name; | |
/** | |
* Returns multi-part encoded form data for use directly in HTTP requests | |
*/ | |
- (NSData *)finalizedData; | |
/** | |
* Returns an appropriate HTTP Content-Type header value that includes | |
* the multipart boundary value | |
*/ | |
- (NSString *)contentType; | |
@end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import "CFMultipartForm.h" | |
static NSString *const CFBodyDataBoundary = @"ThIsIsAcOnTeNtBoUnDaRy"; | |
@interface CFMultipartForm () | |
@property (nonatomic, strong) NSMutableData *data; | |
@end | |
@implementation CFMultipartForm | |
- (id)init { | |
if (self = [super init]) { | |
self.data = [NSMutableData data]; | |
} | |
return self; | |
} | |
#pragma mark - Instance Methods | |
- (void)addFormValue:(NSString *)value forName:(NSString *)name { | |
[self appendBoundary]; | |
[self appendNewline]; | |
[self appendFieldNamed:name]; | |
[self appendNewline]; | |
[self appendNewline]; | |
[self.data appendData:[value dataUsingEncoding:NSUTF8StringEncoding]]; | |
[self appendNewline]; | |
} | |
- (void)addJPEGImage:(UIImage *)image forName:(NSString *)name { | |
[self appendBoundary]; | |
[self appendNewline]; | |
[self appendFieldNamed:name]; | |
[self.data appendData:[@"; filename=\"image.jpeg\"" dataUsingEncoding:NSUTF8StringEncoding]]; | |
[self appendNewline]; | |
[self appendContentType:@"image/jpeg"]; | |
[self appendNewline]; | |
[self appendNewline]; | |
[self.data appendData:UIImageJPEGRepresentation(image, 1.0)]; | |
[self appendNewline]; | |
} | |
- (void)addPNGImage:(UIImage *)image forName:(NSString *)name { | |
[self appendBoundary]; | |
[self appendNewline]; | |
[self appendFieldNamed:name]; | |
[self.data appendData:[@"; filename=\"image.png\"" dataUsingEncoding:NSUTF8StringEncoding]]; | |
[self appendNewline]; | |
[self appendContentType:@"image/png"]; | |
[self appendNewline]; | |
[self appendNewline]; | |
[self.data appendData:UIImagePNGRepresentation(image)]; | |
[self appendNewline]; | |
} | |
// add video to the form | |
- (void)addVideo:(NSData *)videoData forName:(NSString *)name { | |
[self appendBoundary]; | |
[self appendNewline]; | |
[self appendFieldNamed:name]; | |
[self.data appendData:[@"; filename=\"flv\"" dataUsingEncoding:NSUTF8StringEncoding]]; | |
[self appendNewline]; | |
[self appendContentType:@"application/octet-stream"]; | |
[self appendNewline]; | |
[self appendNewline]; | |
[self.data appendData:videoData]; | |
[self appendNewline]; | |
} | |
- (void)addFileAtURL:(NSURL *)URL contentType:(NSString *)contentType fileName:(NSString *)fileName forName:(NSString *)name { | |
[self appendBoundary]; | |
[self appendNewline]; | |
[self appendFieldNamed:name]; | |
[self appendContentType:contentType]; | |
[self appendNewline]; | |
[self appendNewline]; | |
[self.data appendData:[NSData dataWithContentsOfURL:URL]]; | |
[self appendNewline]; | |
} | |
- (NSData *)finalizedData { | |
NSMutableData *dataCopy = [NSMutableData dataWithData:self.data]; | |
NSString *finalBoundary = [NSString stringWithFormat:@"--%@--\r\n", CFBodyDataBoundary]; | |
[dataCopy appendData:[finalBoundary dataUsingEncoding:NSUTF8StringEncoding]]; | |
return [NSData dataWithData:dataCopy]; | |
} | |
- (NSString *)contentType { | |
return [NSString stringWithFormat:@"multipart/form-data; boundary=%@", CFBodyDataBoundary]; | |
} | |
#pragma mark - Private Helpers | |
- (void)appendFieldNamed:(NSString *)name { | |
NSString *string = [NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"", name]; | |
[self.data appendData:[string dataUsingEncoding:NSUTF8StringEncoding]]; | |
} | |
- (void)appendContentType:(NSString *)contentType { | |
NSString *string = [NSString stringWithFormat:@"Content-Type: %@", contentType]; | |
[self.data appendData:[string dataUsingEncoding:NSUTF8StringEncoding]]; | |
} | |
- (void)appendBoundary { | |
[self.data appendData:[@"--" dataUsingEncoding:NSUTF8StringEncoding]]; | |
[self.data appendData:[CFBodyDataBoundary dataUsingEncoding:NSUTF8StringEncoding]]; | |
} | |
- (void)appendNewline { | |
[self.data appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]]; | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment