Our thoughts in real time
« June 2009 | Main | October 2009 »
September 2009
September 23, 2009
Uploading Files from iPhone
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.';
}
}
?>
Posted at 03:53 PM in iPhone | Permalink | Comments (1) | TrackBack (0)
September 21, 2009
Grio Completes Flex App for Compiere, Inc.
Grio has recently completed a custom Adobe Flex application for Compiere, Inc. Compiere delivers the most widely used open source enterprise resource planning (ERP) and customer relationship management (CRM) solution with more than 1.8 million software downloads.
Grio was employed by Compiere to help create a new Flex-based module that will be delivered in Compiere's upcoming release.
Posted at 02:53 PM in News | Permalink | Comments (0) | TrackBack (0)