We recently completed an iPhone application that allows user to, among other things, perform voice-recording and upload the recorded file to a server. For uploading, it uses HTTP multipart POST against an Apache webserver. This type of arrangement is a very common way of sending a file to a webserver. I am certain that similar implementations can be found in several different programming languages. Here is my Objective C implementation...I tried to focus on brevity and encapsulation.
The code:
* Upload a file to a webserver thru http post.
* uid is the http request id
* requestData is list of key/value pairs to be sent along with the file
* url is the destination url
* filePath is absolute file path of the file to be uploaded
*/
- (void)postUpload:(NSString *)url
:(NSString *)uid
:(NSDictionary *)requestData
:(NSString *)filePath
{
NSURL *theURL = [NSURL URLWithString:url];
NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:theURL
cachePolicy:NSURLRequestReloadIgnoringCacheData
timeoutInterval:20.0f];
[theRequest setHTTPMethod:@"POST"];
[theRequest setValue:uid forHTTPHeaderField:@"uid"];
// define post boundary...
NSString *boundary = [[NSProcessInfo processInfo] globallyUniqueString];
NSString *boundaryString = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary];
[theRequest addValue:boundaryString forHTTPHeaderField:@"Content-Type"];
// define boundary separator...
NSString *boundarySeparator = [NSString stringWithFormat:@"--%@\r\n", boundary];
//adding the body...
NSMutableData *postBody = [NSMutableData data];
// adding params...
for (id key in requestData) {
NSString *formDataName = [NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n", key];
NSString *formDataValue = [NSString stringWithFormat:@"%@\r\n", [requestData objectForKey:key]];
[postBody appendData:[boundarySeparator dataUsingEncoding:NSUTF8StringEncoding]];
[postBody appendData:[formDataName dataUsingEncoding:NSUTF8StringEncoding]];
[postBody appendData:[formDataValue dataUsingEncoding:NSUTF8StringEncoding]];
}
// if file is defined, upload it...
if (filePath) {
NSArray *split = [filePath componentsSeparatedByString:@"/"];
NSString *fileName = (NSString*)[split lastObject];
NSData *fileContent = [NSData dataWithContentsOfFile:filePath options:0 error:nil];
[postBody appendData:[boundarySeparator dataUsingEncoding:NSUTF8StringEncoding]];
[postBody appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"audioBody\"; filename=\"%@\"\r\n", fileName] dataUsingEncoding:NSUTF8StringEncoding]];
[postBody appendData:[@"Content-Type: application/octet-stream\r\n\r\n"
dataUsingEncoding:NSUTF8StringEncoding]];
[postBody appendData:fileContent];
}
[postBody appendData:[[NSString stringWithFormat:@"\r\n--%@--\r \n",boundary]
dataUsingEncoding:NSUTF8StringEncoding]];
[theRequest setHTTPBody:postBody];
NSURLResponse *theResponse = NULL;
NSError *theError = NULL;
NSData *reqResults = [NSURLConnection sendSynchronousRequest:theRequest
returningResponse:&theResponse
error:&theError];
if (!reqResults) {
NSLog(@"Connection error for URL: %@", [url description]);
UIAlertView *alert = [UIAlertView alloc];
[[alert initWithTitle:@"Error in connection"
message:[theError localizedDescription]
delegate:self
cancelButtonTitle:nil
otherButtonTitles:@"Quit", nil] autorelease];
[alert show];
}
}
NSArray *keys = [NSArray arrayWithObjects:@"recipients", @"title", @"textBody", nil];
NSArray *objects = [NSArray arrayWithObjects:uids, inputSubject.text, inputMessage.text, nil];
NSDictionary* postData = [NSDictionary dictionaryWithObjects:objects forKeys:keys];
// post now...
[[WebService alloc] postUpload:URL_ENDPOINT_SEND_MESSAGE
:appDelegate.uid
:postData
:[recorder recordFilePath]];
<?php
define('FILE_SAVE_DIRECTORY','/folder/to/save/uploaded/files/');
error_log("Requesting upload file....");
error_log(print_r($_SERVER, true));
error_log("\n\n");
error_log(print_r($_FILES, true));
if($_POST && isset($_FILES['file'])) {
error_log(" the file:...." . $_FILES['file']['name']);
$file = $_FILES['file'];
$dst = FILE_SAVE_DIRECTORY . basename($file['name']);
if (move_uploaded_file($file['tmp_name'], $dst)){
echo 'Upload Successfully: '.$dst;
}
else {
echo 'Error uploading the file.';
}
}
?>







