How to convert NSData into string in iPhone SDK? - iphone

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];
}

Related

post variable containing XML data to a web-server using POST in iPhone

I've looked through a lot of opened questions within similar topic but unfortunately couldn't find the answer.
The thing is I'm new to sending POST/GET messages and I'm not sure How do I need to POST variable containing XML data to a web-server.
"Use POST or GET variable "test" with XML string on a specified URL".
I know how to make connection, and put XML into HTTPBody and make a request. But I don't know how to specify XML for a variable.
Please help.
If by "specify XML for a variable" you mean send an XML string as part of multipart/form-data, then it's easy.
You just have to append your XML string to your request body like you do, but additionaly encapsulate it between boundaries and add a content header.
NSURL *remoteURL = [NSURL URLWithString:#"http://someurl"];
NSMutableURLRequest *imageRequest = [[NSMutableURLRequest alloc] initWithURL:remoteURL];
//A unique string that will be repeated as a separator
NSString *boundary = #"14737809831466499882746641449";
//this is important so the webserver knows that you're sending multipart/form-data
NSString *contentType = [NSString stringWithFormat:#"multipart/form-data; boundary=%#", boundary];
[imageRequest addValue:contentType forHTTPHeaderField: #"Content-Type"];
NSMutableData *body = [NSMutableData data];
[body appendData:[[NSString stringWithFormat:#"\r\n--%#\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]]; //boundary
[body appendData:[#"Content-Disposition: form-data; name=\"xmlString\"\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]]; //your content header
[body appendData:[xmlString dataUsingEncoding:NSUTF8StringEncoding]]; //your content itself
[body appendData:[[NSString stringWithFormat:#"\r\n--%#\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[imageRequest setHTTPMethod:#"POST"]; //set Method as POST
[imageRequest setHTTPBody:body];
NSData *data = [NSURLConnection sendSynchronousRequest:imageRequest returningResponse:nil error:nil];
Or... If you want send a GET variable as part of your query string, just URL encode it and add it as part of your URL.
NSString *xmlString = #"<xml>...</xml>";
NSString *escapedString = [xmlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString *urlString = [NSString stringWithFormat:#"http://someserver/?xmlString=%#",escapedString];
NSURL *url = [NSURL URLWithString:urlString];
NSLog(#"Current URL: %#", url);
This is what a request URL with a HTTP GET parameter looks like.
I hope this helps.

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

HTTPS POST from iPhone using NSURLConnection hangs for certain filesize range

I'm using NSURLConnection to make an async HTTPS POST to our webservice to upload a jpg. It works fine most of the time.
But when the post body is between 196609 and 196868 bytes (inclusive), the connection hangs after the file has been uploaded 100% (didSendBodyData tells me that it's 100% sent). Then after 5 minutes, the connection times out with the message "The network connection was lost." Larger and smaller filesizes work. I've tested this by capping the filesize of the file that I add to the post body.
The content length is getting set correctly. See the code below.
The upload looks fine when I upload to netcat via HTTP. The entire body of the message gets through. But I suspect something's going wrong because of the SSL encryption, like it's buffering an SSL encrypted block frame.
Is there a bug in the iPhone's SSL code that makes it not upload the entire post body even though it's reporting that it is, or something else?
Here's the section where I set the content length and append the file to the multi-part POST body. You can see i'm capping the filesize manually, to test.
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:nsurl];
[request setHTTPMethod:#"POST"];
[request setTimeoutInterval:1];
[request addValue:#"close" forHTTPHeaderField: #"Connection"];
// Add headers and POST information
NSLog( #"Posting file." );
NSString *stringBoundary = [NSString stringWithString:#"0xKhTmLbOuNdArY"];
NSString *contentType = [NSString stringWithFormat:#"multipart/form-data; boundary=%#",stringBoundary];
[request addValue:contentType forHTTPHeaderField: #"Content-Type"];
NSMutableData *postBody = [NSMutableData data];
...
[postBody appendData:[[NSString stringWithFormat:#"--%#\r\n",stringBoundary] dataUsingEncoding:NSUTF8StringEncoding]];
[postBody appendData:[[NSString stringWithString:#"Content-Disposition: form-data; name=\"uploadFile\"; filename=\"upload.jpg\"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
[postBody appendData:[[NSString stringWithString:#"Content-Type: image/jpg\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
NSLog( #"file size...%d", [uploadFile length] );
//[postBody appendData:uploadFile];
[postBody appendData:[NSData dataWithBytes: [uploadFile bytes] length: 196099]];
[postBody appendData:[[NSString stringWithFormat:#"\r\n--%#--\r\n",stringBoundary] dataUsingEncoding:NSUTF8StringEncoding]];
[request setHTTPBody:postBody];
[request setValue:[NSString stringWithFormat:#"%d", [postBody length]] forHTTPHeaderField:#"Content-Length"];
NSLog(#"Uploaded POST size: %d", [postBody length] );
Ah, I've found what the issue is. Connection: Keep-alive is being set, even though I set connection: close. How do I override this?? It looks like you can't!?
I have following code that is tested for 30-40 MB of files, and it never hangs. It looks almost similar to your code, however are you sure that its not your server side scrip that may be waiting for something?
url = [NSURL URLWithString:u];
NSData* d = [self data];
request = [NSMutableURLRequest requestWithURL:url];
[request setTimeoutInterval: 2000 ];
[request setHTTPMethod:#"POST"];
[request setValue:
[NSString stringWithFormat:#"multipart/form-data; boundary=%#", BOUNDRY]
forHTTPHeaderField:#"Content-Type"];
NSMutableData *postData =
[NSMutableData dataWithCapacity:[d length] + 512];
[postData appendData:
[[NSString stringWithFormat:#"--%#\r\n", BOUNDRY] dataUsingEncoding:NSUTF8StringEncoding]];
[postData appendData:
[[NSString stringWithFormat:
#"Content-Disposition: form-data; name=\"%#\"; filename=\"file.bin\"\r\n\r\n", FORM_FLE_INPUT]
dataUsingEncoding:NSUTF8StringEncoding]];
[postData appendData:d];
[postData appendData:
[[NSString stringWithFormat:#"\r\n--%#--\r\n", BOUNDRY] dataUsingEncoding:NSUTF8StringEncoding]];
[request setHTTPBody:postData];
I think you can try to remove this line of codes.
[request addValue:#"close" forHTTPHeaderField: #"Connection"];
It will tell the http server to close this connection. By the RFC 2616 (HTTP/1.1), servers and clients should maintain persistent connection.

UIImage uploading using NSMutable request

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];

iPhone : upload image to web aspx file

I have a little problem.
I have to upload a photo from my iPhone to a web server with POST Method but the server file is in aspx.
I tried my code with my server and PHP file : works well !
Now with aspx file : doesn't upload :(
I don't havec access to the .aspx .
Here is my iphone code :
NSData *imageData = UIImageJPEGRepresentation(imageView.image,70);
NSString *urlString = #"http://iphone.domain.net/upload_photos.aspx";
NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease];
[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",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:#"Content-Disposition: form-data; name=\"photo\"; filename=\"%#.jpg\"\r\n",[c nom]] 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];
I think the problem comes from the Content-Type or for my dataUsingEncoding: parameter.
Have you got and idea to solve it?
If you're not opposed to using a 3rd party library consider looking at ASIHttpRequest. It'll make your life so much easier:
http://allseeing-i.com/ASIHTTPRequest/
http://allseeing-i.com/ASIHTTPRequest/How-to-use
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
// Upload a file on disk
[request setFile:#"/Users/ben/Desktop/ben.jpg" withFileName:#"myphoto.jpg" andContentType:#"image/jpeg"
forKey:#"photo"];
// Upload an NSData instance
[request setData:imageData withFileName:#"myphoto.jpg" andContentType:#"image/jpeg" forKey:#"photo"];
normally, the boundary does not contain the --- when it's specified in the Content-Type. Apart from that, can't see anything unusual.
Try to upload it to the aspx server from the command line with curl. Once you've got that working, pass -v (verbose) or -i (include HTTP headers) to check exactly what is being sent, and then you can try to replicate that in Cocoa.