UIImage uploading using NSMutable request - iphone

I need to POST a request. The request has 3 parameters, 'email_id' , 'location' and 'image_data'. The value for 'image_data' contains NSData jpeg representation of a UIImage. The request must be submitted using a content type of multipart/form-data. How can I create the NSMutableRequest for posting this request? How should I set the boundary? Is the boundary required for the entire packet or is it enough only for the image part?

This link:
http://iphone.zcentric.com/2008/08/29/post-a-uiimage-to-the-web/
Should contain all you need. U'll need to extend the PHP-script to handle your non-image parameters but this is what I used. :)
Edit: Noticed the previous link was broken. The new one works

If I were you, I'd check out the ASIHTTPRequest library. It's an HTTP client library for Cocoa that makes life EVER so much easier for people who do a lot of web interactions from their iPhone apps.
Here's me, using ASIFormDataRequest (a component of ASIHTTPRequest) to upload an image from my iPhone app. The client's term for these images is "marks"--they're going on a map of local pictures taken by users all around the local area. Users are invited to "make your mark". You can imagine the hilarity that ensues.
Anyhoo, self.mark is an instance of my Mark class that encapsulates the data about an image-and-details package I'm uploading. I have a data manager singleton I use in the first line of this method, which contains the current CLLocation, so I can get geocode info for this picture.
Notice I don't concern myself with encoding types or multipart boundaries. The library handles all that.
-(void)completeUpload
{
CLLocation *currentLoc = [DataManager sharedDataManager].currentLocation;
self.mark.latitude = [NSNumber numberWithDouble:currentLoc.coordinate.latitude];
self.mark.longitude = [NSNumber numberWithDouble:currentLoc.coordinate.longitude];
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:
[NSURL URLWithString:[NSString stringWithFormat:#"%#image_upload.php", WEBAPPURL]]];
[request setPostValue:self.mark.titleText forKey:#"title"];
[request setPostValue:self.mark.descriptionText forKey:#"description"];
[request setPostValue:self.mark.event.guid forKey:#"event"];
[request setPostValue:self.mark.latitude forKey:#"latitude"];
[request setPostValue:self.mark.longitude forKey:#"longitude"];
[request setPostValue:self.mark.project forKey:#"project"];
[request setPostValue:[[NSUserDefaults standardUserDefaults] valueForKey:#"userID"] forKey:#"user_id"];
request.timeOutSeconds = 120;
int i = 1;
for (NSString *tag in self.tags) {
[request setPostValue:tag forKey:[NSString stringWithFormat:#"tag-%d", i]];
i++;
}
NSData *imageData = UIImagePNGRepresentation(self.mark.image);
NSData *thumbData = UIImagePNGRepresentation(self.mark.thumbnail);
[request setData:imageData forKey:#"file"];
[request setData:thumbData forKey:#"thumb"];
self.progress.progress = 20.0;
[request setUploadProgressDelegate:self.progress];
request.showAccurateProgress = YES;
request.delegate = self;
[request startAsynchronous];
}
EDIT: By the way, the PHP script I'm posting to is behind HTTP authentication. ASI caches those credentials, and I provided them earlier, so I don't have to provide them again here. I note that because otherwise, the way this post and the corresponding PHP script is written, anybody could fake anybody else's user ID value and post whatever under their username. You have to think about web-application security when you build an app like this, no different than if it was a web site. It IS a web site, actually, just browsed through a non-traditional client.

NSData *imageData=UIImageJPEGRepresentation(imageview.image, 1.0);
NSString *filename=#"nike.jpg"
NSString *urlString = #"http://xyz.com/file_upload/file1.php";
NSMutableURLRequest *request =[[[NSMutableURLRequest alloc] init] autorelease];
[request setURL:[NSURL URLWithString:urlString]];
[request setHTTPMethod:#"POST"];
NSString *boundary = [NSString stringWithString:#"-----------------99882746641449"];
NSString *contentType = [NSString stringWithFormat:#"multipart/form-data; boundary=%#",boundary];
[request addValue:contentType forHTTPHeaderField: #"Content-Type"];
NSMutableData *body = [NSMutableData data];
NSMutableString * string = [[NSMutableString alloc] init];
[string appendFormat:#"\r\n\r\n--%#\r\n", boundary];
[string appendFormat:#"Content-Disposition: form-data; name=\"emailid\"\r\n\r\n"];
[string appendFormat:#"pradz39#gmail.com"]; //value
[body appendData:[string dataUsingEncoding:NSUTF8StringEncoding]]; // encrypt the entire body
[body appendData:[[NSString stringWithFormat:#"\r\n--%#\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithString:[NSString stringWithFormat:#"Content-Disposition: form-data; name=\"userfile\"; filename=\"%#\"\r\n",filename]] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithString:#"Content-Type: application/octet-stream\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[NSData dataWithData:imageData]];
[body appendData:[[NSString stringWithFormat:#"\r\n--%#--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[string release];
[request setHTTPBody:body];
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSString *returnString = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];

Related

How to get Upload time remaining from Asynchronous Request?

I m trying to upload an Image from iPhone to Server. I m Able to Do so But i need to show an Indicator.My code is
NSData *imageData = UIImageJPEGRepresentation(newImage, 90);
// setting up the URL to post to
NSString *urlString = [NSString stringWithFormat:#"URL",[[formater stringFromDate:now] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
// setting up the request object now
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init] ;
[request setURL:[NSURL URLWithString:urlString]];
[request setHTTPMethod:#"POST"];
NSString *boundary = [NSString stringWithFormat:#"---------------------------14737809831466499882746641449"];
NSString *contentType = [NSString stringWithFormat:#"multipart/form-data; boundary=%#",boundary];
[request addValue:contentType forHTTPHeaderField: #"Content-Type"];
NSMutableData *body = [NSMutableData data];
[body appendData:[[NSString stringWithFormat:#"\r\n--%#\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:#"Content-Disposition: form-data; name=\"image\"; filename=\"ipodfile.jpg\"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:#"Content-Type: application/octet-stream\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[NSData dataWithData:imageData]];
[body appendData:[[NSString stringWithFormat:#"\r\n--%#--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
// setting the body of the post to the reqeust
[request setHTTPBody:body];
Here is the code to fire request.
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
NSLog(#"Finished with status code: %i", [(NSHTTPURLResponse *)response statusCode]);
}];
So How can i Calculate the Remaining time so that i can Show an indicator ?
Thanks for your time.
You can use this method of connection delegate:
- (void) connection:(NSURLConnection *)connection
didSendBodyData:(NSInteger)bytesWritten
totalBytesWritten:(NSInteger)totalBytesWritten
totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite;
(How should I wrap such long argument names?)
It's not in documentation of NSURLConnectionDataDelegate, but if you check the public header NSURLConnection.h, it's there. So don't worry about using it.
From documentation URL Loading System Programming Guide > Using NSURLConnection:
Estimating Upload Progress
You can estimate the progress of an HTTP POST upload with the connection:didSendBodyData:totalBytesWritten:totalBytesExpectedToWrite: delegate method. Note that this is not an exact measurement of upload progress, because the connection may fail or the connection may encounter an authentication challenge.
I believe you want to show something like a progress bar. I recomend using the MKNetworkKit that provides you many tools for network management, such as progress of an asynchronous connection. Check this link.

how to post an image to the web server

I am working with web services using json parsing. I am able to get images from the web services, can someone help me how to post an image? How i can post an image to the web services?
it will be something along the lines of this...
NSMutableURLRequest *mutableRequest = [[NSMutableURLRequest alloc] initWithURL:#"you url"];
[mutableRequest addValue:#"image/jpeg" forHTTPHeaderField: #"Content-Type"];
NSMutableData *body = [NSMutableData data];
[body appendData:[NSData dataWithData:UIImageJPEGRepresentation(self.image, 0.9)]];
[mutableRequest setHTTPBody:body];
NSURLResponse *response;
NSError *error;
(void) [NSURLConnection sendSynchronousRequest:mutableRequest returningResponse:&response error:&error];
Thanks
Find here serverside (PHP) coding for image Upload with random name. also it will give the image link as response.
//Create a folder named images in your server where you want to upload the image.
// And Create a PHP file and use below code .
<?php
$uploaddir = 'images/';
$ran = rand () ;
$file = basename($_FILES['userfile']['name']);
$uploadfile = $uploaddir .$ran.$file;
if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) {
echo "www.host.com/.../images/{$uploadfile}";
}
?>
And Here is iOS code
- (IBAction)uploadClicked:(id)sender
{
/*
turning the image into a NSData object
getting the image back out of the UIImageView
setting the quality to 90
*/
NSData *imageData = UIImageJPEGRepresentation(imageView.image, 90);
// setting up the URL to post to
NSString *urlString = #"your URL link";
// setting up the request object now
NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease];
[request setURL:[NSURL URLWithString:urlString]];
[request setHTTPMethod:#"POST"];
/*
add some header info now
we always need a boundary when we post a file
also we need to set the content type
You might want to generate a random boundary.. this is just the same
as my output from wireshark on a valid html post
*/
NSString *boundary = [NSString stringWithString:#"---------------------------14737809831466499882746641449"];
NSString *contentType = [NSString stringWithFormat:#"multipart/form-data; boundary=%#",boundary];
[request addValue:contentType forHTTPHeaderField: #"Content-Type"];
/*
now lets create the body of the post
*/
NSMutableData *body = [NSMutableData data];
[body appendData:[[NSString stringWithFormat:#"rn--%#rn",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithString:#"Content-Disposition: form-data; name="userfile"; filename="ipodfile.jpg"rn"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithString:#"Content-Type: application/octet-streamrnrn"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[NSData dataWithData:imageData]];
[body appendData:[[NSString stringWithFormat:#"rn--%#--rn",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
// setting the body of the post to the reqeust
[request setHTTPBody:body];
// now lets make the connection to the web
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSString *returnString = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];
NSLog(returnString);
}
Check below good tutorial.In that tutorial you able to find the ios side code as well server side php code too.
http://zcentric.com/2008/08/29/post-a-uiimage-to-the-web/
The best way to use ASIHttpFormData Click here to know how to use

Error sending http post request with image

I'm stucked in this problem since days and i really need your help.
I'm actually trying to upload a file from my iphone app to a webserver trough a php script.
this is my method in Xcode:
-(void)sendPost{
UIImageView *imageView = [[UIImageView alloc] init];
imageView.image = [UIImage imageNamed:#"back.png"];
NSData *imageData = UIImageJPEGRepresentation(imageView.image, 90);
NSString *urlString = #"myscriptishere.php";
NSMutableURLRequest *request = [[NSMutableURLRequest alloc]init];
[request setTimeoutInterval:60.0];
[request setURL:[NSURL URLWithString:urlString]];
[request setHTTPMethod:#"POST"];
NSString *boundary = [NSString stringWithString:#"---------------------------14737809831466499882746641449"];
NSString *contentType = [NSString stringWithFormat:#"multipart/form-data; boundary=%#",boundary];
[request addValue:contentType forHTTPHeaderField:#"Content-Type"];
NSMutableData *body = [NSMutableData data];
[body appendData:[[NSString stringWithFormat:#"\r\n--%#\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithString:#"Content-Disposition: form-data; name=\"userfile\";filename=\"myfile.png\"\r\n"]
dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithString:#"Content-Type: application/octet-stream\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[NSData dataWithData:imageData]];
[body appendData:[[NSString stringWithFormat:#"\r\n--%#\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[request setHTTPBody:body];
NSLog(#"%#",[[NSString alloc] initWithData:[NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil] encoding:NSUTF8StringEncoding]);
// Do any additional setup after loading the view.
}
and my php code is:
<?php
$domainpath = $_SERVER['DOCUMENT_ROOT'];
$target = "./upload";
$public = "/public/upload/";
$target = $target.basename( $_FILES['userfile']['name']) ;
$check = getimagesize($_FILES['userfile']['tmp_name']);
if (move_uploaded_file($_FILES["file"]["tmp_name"],
$domainpath. $public . $_FILES["file"]["name"]))
echo "YES";
else
echo "NO";
?>
I always receive (after few seconds, so I guess I'm uploading something) the server reply "NO".
I already checked I have permission on the folder I'm going to write in.
Any ideas on where the problem could be hidin?
Thanx in advance
Your problem is here:
NSString *urlString = #"myscriptishere.php";
NSMutableURLRequest *request = [[NSMutableURLRequest alloc]init];
[request setTimeoutInterval:60.0];
[request setURL:[NSURL URLWithString:urlString]];
You are posting to a filename. Your urlString variable should hold full address including protocol and domain (like #"http://localhost/myscriptishere.php").

Blank image with POST

I've an issue with the post of an UIImage on a PHP server, when I post it, the image received is empty.
The method I use is :
- (void)uploadImage {
/*
turning the image into a NSData object
getting the image back out of the UIImageView
setting the quality to 90
*/
NSData *imageData = UIImageJPEGRepresentation(myImage, 0.9);
// setting up the URL to post to
NSString *urlString = #"http://myserver/test.php";
// setting up the request object now
NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease];
[request setURL:[NSURL URLWithString:urlString]];
[request setHTTPMethod:#"POST"];
/*
add some header info now
we always need a boundary when we post a file
also we need to set the content type
You might want to generate a random boundary.. this is just the same
as my output from wireshark on a valid html post
*/
NSString *boundary = [NSString stringWithString:#"---------------------------14737809831466499882746641449"];
NSString *contentType = [NSString stringWithFormat:#"multipart/form-data; boundary=%#",boundary];
[request addValue:contentType forHTTPHeaderField: #"Content-Type"];
/*
now lets create the body of the post
*/
NSMutableData *body = [NSMutableData data];
[body appendData:[[NSString stringWithFormat:#"\r\n--%#\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithString:#"Content-Disposition: form-data; name=\"userfile\"; filename=\"ipodfile.jpg\"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithString:#"Content-Type: application/octet-stream\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[NSData dataWithData:imageData]];
[body appendData:[[NSString stringWithFormat:#"\r\n--%#--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
// setting the body of the post to the reqeust
[request setHTTPBody:body];
// now lets make the connection to the web
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSString *returnString = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];
NSLog(returnString);
}
Taken from : http://iphone.zcentric.com/2008/08/29/post-a-uiimage-to-the-web/
Thanks for your help !
I suggest the use of ASIHTTPRequest for this kind of requests. You can do this much more easily with it. Here is an example to how send an image using ASIHTTPRequest:
// Initilize Queue
networkQueue = [[ASINetworkQueue alloc] init];
[networkQueue setUploadProgressDelegate:statusProgressView];
[networkQueue setRequestDidFinishSelector:#selector(imageRequestDidFinish:)];
[networkQueue setQueueDidFinishSelector:#selector(imageQueueDidFinish:)];
[networkQueue setRequestDidFailSelector:#selector(requestDidFail:)];
[networkQueue setShowAccurateProgress:true];
[networkQueue setDelegate:self];
NSData *imageData = UIImageJPEGRepresentation(yourImage, compression);
url = [NSURL URLWithString:#"http://myserver/upload.php"];
ASIFormDataRequest *request = [[[ASIFormDataRequest alloc] initWithURL:url] autorelease];
[request setPostValue:#"myImageName" forKey:#"name"];
[request addData:imageData withFileName:#"someFileName.jpeg" andContentType:#"image/jpeg" forKey:#"uploadedImage"];
[networkQueue addOperation:request];
[networkQueue go];
Hope it helps

How to convert NSData into string in iPhone SDK?

I am developing an iPhone application in which camera image store in NSData through UIImageJPEGRepresentation now i want to convert this NSData into string. After goggling I found base64 will do this.
I want to know that if i encode it into base64 and then send it to php server, then it is possible to decode it and convert into Image.
I first ask here how to send Image with coordinates and image description to php server but i cannot got response, so now i think to convert image into base64 and then send it to php server with coordinates and image description.
Hope someone know the solution !
That doesn't sound good to me. Some http clients provide nice support for image upload. Take a look at ASIHttpRequest. You can save the data to a temp file then upload that file. I didn't use addData method before, looks like you can upload NSData object directly.
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
[request addPostValue:#"Ben" forKey:#"names"];
[request addPostValue:#"George" forKey:#"names"];
[request addFile:#"/Users/ben/Desktop/ben.jpg" forKey:#"photos"];
[request addData:imageData withFileName:#"george.jpg" andContentType:#"image/jpeg" forKey:#"photos"];
Take a look at the following url. It may give you what you are looking for.
http://www.iphonedevsdk.com/forum/iphone-sdk-development/49247-posting-image-web-server-using-soap.html
Base64 is a standard and is supported by most languages including PHP, so it would work.
But this is probably not the best way to do it, as base64 increases the payload size by 33%. You should look into sending it as binary and not string, this will also better support streaming and will use less memory and work faster both on client and server.
You should use base64 only on small data or when there are no better options.
follow this code to send images and variables to server -
// Implement this method in your code to do something with the image.
- (void)useImage:(UIImage*)theImage
{
/*
turning the image into a NSData object
getting the image back out of the UIImageView
setting the quality to 90
*/
NSData *imageData = UIImageJPEGRepresentation(theImage, 90);
// setting up the URL to post to
NSString *urlString=[SiteUrl stringByAppendingString:#"iphone_upload_photo.php?type=colleague&token="];
urlString=[urlString stringByAppendingString:PublicToken];
// setting up the request object now
NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease];
[request setURL:[NSURL URLWithString:urlString]];
[request setHTTPMethod:#"POST"];
/*
add some header info now
we always need a boundary when we post a file
also we need to set the content type
You might want to generate a random boundary.. this is just the same
*/
NSString *boundary = [NSString stringWithString:#"---------------------------14737809831466499882746641449"];
NSString *contentType = [NSString stringWithFormat:#"multipart/form-data; boundary=%#",boundary];
[request addValue:contentType forHTTPHeaderField: #"Content-Type"];
/*
now lets create the body of the post
*/
NSMutableData *body = [NSMutableData data];
[body appendData:[[NSString stringWithFormat:#"\r\n--%#\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithString:#"Content-Disposition: form-data; name=\"userfile\"; filename=\"ipodfile.jpg\"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithString:#"Content-Type: application/octet-stream\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[NSData dataWithData:imageData]];
[body appendData:[[NSString stringWithFormat:#"\r\n--%#--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
// setting the body of the post to the reqeust
[request setHTTPBody:body];
// now lets make the connection to the web
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSString *returnString = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];
[self LoadContent];
}