Skip to content

Instantly share code, notes, and snippets.

@tobitech
Last active February 20, 2017 21:13
Show Gist options
  • Save tobitech/1d1db93bf14cf7989c3267c09e6cd035 to your computer and use it in GitHub Desktop.
Save tobitech/1d1db93bf14cf7989c3267c09e6cd035 to your computer and use it in GitHub Desktop.
Multipart form for uploading data over HTTP
#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
#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