I want to upload an image in png format to a server.I have to give three parameters with the request which are
transactionID: (any random integer)
signatureBytes:data:image/png;base64,iVBORw0KGgoAAAsdffsdfsdfsdfsdfYAAAAeGRPoAAAgAElEQVR4nO2de5BmRXnGHzWmYkKVKUqJRk0erwerrwds55/lVnT/mm+87/Z4+3f30+/YN6D9L48CMA9VxnOJ9S
guid: CAD1CBE7-B5A4-43d6-BCDD-89B16F97E3C4
I have used the code:
NSData *imageData = UIImageJPEGRepresentation(image.image,90);
// setting up the URL to post to
NSString *urlString=#"http://www.riverport.net/icalibur/dev/signature.ashx";
// setting up the request object now
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--%#\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithString:#"Content-Disposition: form-data; name=\"transactionID\"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[[NSString stringWithString:#"7" intva] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithString:#"Content-Disposition: form-data; name=\"signatureBytes\"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithString:#"data:image/png;base64,iVBUaBCrFDXGSIECEXEFdUFEhEVAluXmsrrtrrttrrqddcsvrgergergg/YN6D9L4uozc5h+nsWsFhGSn88CWAAwqV2ynoz1qvJjYTmfCOk1QxJ0ANgHijoZDy8CMA9VxnOJ9S"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithString:#"Content-Disposition: form-data; name=\"guid\"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithString:#"CHJ78G-B5A4-43d6-BCDD-CFG567FGJ"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithString:#"Content-Disposition: form-data; name=\"userfile\"; filename=\"ipodfile.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]];
// setting the body of the post to the reqeust
[request setHTTPBody:body];
NSString* returns= [[NSString alloc] initWithData:body encoding:NSUTF8StringEncoding];
//NSLog(#"body %#",stri);
// 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);
and the response from server is:
[FormatException: Input string was not in a correct format.]
Microsoft.VisualBasic.CompilerServices.Conversions.ParseDouble(String Value, NumberFormatInfo NumberFormat) +201
Microsoft.VisualBasic.CompilerServices.Conversions.ToInteger(String Value) +66
[InvalidCastException: Conversion from string "����
Have anybody any idea What could be the problem.I do not know if i am doing it right .
From the errors you received i believe that you don't set your parameters correctly for the request.
Why don't you use ASIHTTPRequest to upload your photo? it has a class ASIFormDataRequest that you can use to make POST or GET requests and you can add parameters to it really easy.
here is an example of uploading images with ASIHTTPRequest.
You're not formatting the upload data correctly. The post data should look something like this:
--boundary
Content-Disposition: form-data; name="foo"
value-for-foo
--boundary
Content-Disposition: form-data; name="bar"
value-for-bar
--boundary
Content-Disposition: form-data; name="file"; filename="filename.ext"
Content-Type: application/whatever
file data
--boundary--
Note how there is a blank line ("\r\n\r\n") in between the headers and the value of the field, a crlf after the value, and a repeat of the boundary before the next field's header. You have none of that in your code, your output looks more like this:
--boundary
Content-Disposition: form-data; name="foo"
value-for-fooContent-Disposition: form-data; name="bar"
value-for-barContent-Disposition: form-data; name="file"; filename="filename.ext"
Content-Type: application/whatever
file data--boundary--
Hi Pankaj
I am not sure but just try only image NSData with out transactionID and guide parameter,
your code seems ok.
Please let me know result.
You say you want to post a PNG-image but you are fetching the JPEG-representation in your code-snippet. Is it solved by changing to UIImagePNGRepresentation?
Related
I am trying to post values & file over HTTP in an IPhone app.
The requirement is when the form is posted, the values in the input boxes has to be used for authentication and if the user is valid, the file should get uploaded.
But when I try to post the form, the file is not getting posted and also the posted values are not accepted by the action URL.
Find below the code used in the IPhone app and its HTML equivalent. Can someone tell what I am missing?
HTML Equivalent
<form action="http://www.something.com/upload/" method="post" enctype="multipart/form-data" target="_blank" onsubmit="return window.confirm("You are submitting information to an external page.\nAre you sure?");">
<h3>Test Form</h3>
<p>File: <input name="file" type="file"></p>
<p>Username: <input name="usr" type="text"></p>
<p>Password: <input name="pwd" type="text"></p>
<p><input name="send" value="Upload" type="submit"></p>
</form>
Code used in IPhone app
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"test-upload" ofType:#"zip"];
NSData *postData = [NSData dataWithContentsOfFile:filePath];
NSString *urlString = #"http://www.something.com/upload/";
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%#\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[#"Content-Disposition: form-data; name=\"usr\"\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[#"usr#domain.com" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:#"\r\n%#\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[#"Content-Disposition: form-data; name=\"pwd\"\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[#"testpwd" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:#"\r\n--%#\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithString:#"Content-Disposition: form-data; name=\"file\"; filename=\"test-upload.zip\"rn"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithString:#"Content-Type: application/octet-stream\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[NSData dataWithData:postData]];
[body appendData:[[NSString stringWithFormat:#"\r\n--%#--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[request setHTTPBody:body];
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSString *returnString = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];
NSLog(returnString);
Looks like you've got a problem with this line:
[body appendData:[[NSString stringWithString:#"Content-Disposition: form-data; name=\"file\"; filename=\"test-upload.zip\"rn"] dataUsingEncoding:NSUTF8StringEncoding]];
Shouldn't that be:
[body appendData:[[NSString stringWithString:#"Content-Disposition: form-data; name=\"file\"; filename=\"test-upload.zip\"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
?
Finally solved by correcting the boundary. I have posted the whole code below
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"test-upload" ofType:#"zip"];
NSData *postData = [NSData dataWithContentsOfFile:filePath];
NSString *urlString = #"http://www.something.com/upload/";
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:[#"Content-Disposition: form-data; name=\"usr\"\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[#"user#domain.com" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithString:#"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:#"--%#\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[#"Content-Disposition: form-data; name=\"pwd\"\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[#"testpwd" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithString:#"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:#"--%#\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithString:#"Content-Disposition: form-data; name=\"file\"; filename=\"test-upload.zip\"rn"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithString:#"Content-Type: application/octet-stream\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[NSData dataWithData:postData]];
[body appendData:[[NSString stringWithFormat:#"\r\n--%#--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[request setHTTPBody:body];
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSString *returnString = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];
NSLog(returnString);
In my application i want to upload the images to server.
I am able to upload images on server but the name of the image mention in front of filename=%#.jpg. remains the same for images
[body appendData:[[NSString stringWithString:#"Content-Disposition: form-data; name=\"userfile\"; filename=\"%#.jpg\"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
but i want to save the image on server with the same image name it has......
plz help me out.
following is my code:
-(IBAction)upload:(id)sender
{
//imageview is a UIImageView
NSData *imageData = UIImageJPEGRepresentation(imageView.image, 100);
// setting up the URL to post to
NSString *urlString = #"http://url.com/upload/uploader.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=\"%#.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];
///self.returnString = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];
NSString *returnString = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];
NSLog(#"%#",returnString);
}
change
[body appendData:[[NSString stringWithString:#"Content-Disposition: form-data; name=\"userfile\"; filename=\"%#.jpg\"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
to
[body appendData:[[NSString stringWithFormat:#"Content-Disposition: form-data; name=\"userfile\"; filename=\"%#.jpg\"\r\n",filename] dataUsingEncoding:NSUTF8StringEncoding]];
where filename is a NSString* variable with your desired filename
this line
[body appendData:[[NSString stringWithString:#"Content-Disposition: form-data; name=\"userfile\"; filename=\"%#.jpg\"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
Content-Type: image/jpeg
instead of Content-Disposition: form-data
and learn how to use content type
I have been combing through the many many posts about uploading images via POST in iOS. Despite the wealth of information on this topic, I cannot manage to correctly upload JPEG data taken from my iPhone Simulator Photo Library.
The data, once on the server, is just a huge string of hexidecimal. Shouldn't NSData just be a byte stream? I don't get whats going on with all the hex, or why this code seems to work for everyone else.
Here is the code in question:
-(void)uploadWithUserLocationString:(NSString*)userLocation{
NSString *urlString = #"http://some.url.com/post";
// set up the form keys and values (revise using 1 NSDictionary at some point - neater than 2 arrays)
NSArray *keys = [[NSArray alloc] initWithObjects:#"auth",#"text",#"location",nil];
NSArray *vals = [[NSArray alloc] initWithObjects:self.authToken,self.textBox.text,userLocation,nil];
// set up the request object
NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease];
[request setURL:[NSURL URLWithString:urlString]];
[request setHTTPMethod:#"POST"];
//Add content-type to Header. Need to use a string boundary for data uploading.
NSString *boundary = [NSString stringWithString:#"0xKhTmLbOuNdArY"];
NSString *contentType = [NSString stringWithFormat:#"multipart/form-data; boundary=%#",boundary];
[request addValue:contentType forHTTPHeaderField: #"Content-Type"];
//create the post body
NSMutableData *body = [NSMutableData data];
[body appendData:[[NSString stringWithFormat:#"--%#\r\n",boundary] dataUsingEncoding:NSASCIIStringEncoding]];
//add (key,value) pairs (no idea why all the \r's and \n's are necessary ... but everyone seems to have them)
for (int i=0; i<[keys count]; i++) {
[body appendData:[[NSString stringWithFormat:#"Content-Disposition: form-data; name=\"%#\"\r\n\r\n",[keys objectAtIndex:i]] dataUsingEncoding:NSASCIIStringEncoding]];
[body appendData:[[NSString stringWithFormat:#"%#",[vals objectAtIndex:i]] dataUsingEncoding:NSASCIIStringEncoding]];
[body appendData:[[NSString stringWithFormat:#"\r\n--%#\r\n",boundary] dataUsingEncoding:NSASCIIStringEncoding]];
}
[body appendData:[[NSString stringWithString:#"Content-Disposition: form-data; name=\"image\"\r\n"] dataUsingEncoding:NSASCIIStringEncoding]];
[body appendData:[[NSString stringWithString:#"Content-Type: application/octet-stream\r\n\r\n"] dataUsingEncoding:NSASCIIStringEncoding]];
[body appendData:[NSData dataWithData:self.imageData]];
[body appendData:[[NSString stringWithFormat:#"\r\n--%#--\r\n",boundary] dataUsingEncoding:NSASCIIStringEncoding]];
// set the body of the post to the reqeust
[request setHTTPBody:body];
// 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);
[keys release];
[vals release];
}
Thanks for your time.
This code works in my app. If you're not using ARC you'll need to modify the code to release anything alloc'ed.
// create request
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];
[request setHTTPShouldHandleCookies:NO];
[request setTimeoutInterval:30];
[request setHTTPMethod:#"POST"];
// set Content-Type in HTTP header
NSString *contentType = [NSString stringWithFormat:#"multipart/form-data; boundary=%#", boundary];
[request setValue:contentType forHTTPHeaderField: #"Content-Type"];
// post body
NSMutableData *body = [NSMutableData data];
// add params (all params are strings)
for (NSString *param in _params) {
[body appendData:[[NSString stringWithFormat:#"--%#\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:#"Content-Disposition: form-data; name=\"%#\"\r\n\r\n", param] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:#"%#\r\n", [_params objectForKey:param]] dataUsingEncoding:NSUTF8StringEncoding]];
}
// add image data
NSData *imageData = UIImageJPEGRepresentation(imageToPost, 1.0);
if (imageData) {
[body appendData:[[NSString stringWithFormat:#"--%#\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:#"Content-Disposition: form-data; name=\"%#\"; filename=\"image.jpg\"\r\n", FileParamConstant] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithString:#"Content-Type: image/jpeg\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:imageData];
[body appendData:[[NSString stringWithFormat:#"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
}
[body appendData:[[NSString stringWithFormat:#"--%#--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
// setting the body of the post to the reqeust
[request setHTTPBody:body];
// set URL
[request setURL:requestURL];
i hope this code will help some body else ...
//create request
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
//Set Params
[request setHTTPShouldHandleCookies:NO];
[request setTimeoutInterval:60];
[request setHTTPMethod:#"POST"];
//Create boundary, it can be anything
NSString *boundary = #"------VohpleBoundary4QuqLuM1cE5lMwCy";
// set Content-Type in HTTP header
NSString *contentType = [NSString stringWithFormat:#"multipart/form-data; boundary=%#", boundary];
[request setValue:contentType forHTTPHeaderField: #"Content-Type"];
// post body
NSMutableData *body = [NSMutableData data];
//Populate a dictionary with all the regular values you would like to send.
NSMutableDictionary *parameters = [[NSMutableDictionary alloc] init];
[parameters setValue:param1 forKey:#"param1-name"];
[parameters setValue:param2 forKey:#"param2-name"];
[parameters setValue:param3 forKey:#"param3-name"];
// add params (all params are strings)
for (NSString *param in parameters) {
[body appendData:[[NSString stringWithFormat:#"--%#\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:#"Content-Disposition: form-data; name=\"%#\"\r\n\r\n", param] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:#"%#\r\n", [parameters objectForKey:param]] dataUsingEncoding:NSUTF8StringEncoding]];
}
NSString *FileParamConstant = #"imageParamName";
NSData *imageData = UIImageJPEGRepresentation(imageObject, 1);
//Assuming data is not nil we add this to the multipart form
if (imageData)
{
[body appendData:[[NSString stringWithFormat:#"--%#\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:#"Content-Disposition: form-data; name=\"%#\"; filename=\"image.jpg\"\r\n", FileParamConstant] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[#"Content-Type:image/jpeg\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:imageData];
[body appendData:[[NSString stringWithFormat:#"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
}
//Close off the request with the boundary
[body appendData:[[NSString stringWithFormat:#"--%#--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
// setting the body of the post to the request
[request setHTTPBody:body];
// set URL
[request setURL:[NSURL URLWithString:baseUrl]];
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response;
if ([httpResponse statusCode] == 200) {
NSLog(#"success");
}
}];
Take a look at Apple's SimpleURLConnections example project. You can use the PostController from there with a few modifications.
However - it's not exactly simple. The difference to the solution above is that Apple's is using a stream to stream the file to the server. That's much more memory-friendly than keeping the encoded image data around for the duration of the upload. It's also way more complicated.
NSData *imgData = UIImagePNGRepresentation(imgUser.image);
NSString *str=[NSString stringWithFormat:#"%#upload_image",appDelegate.strRoot];
NSString *urlString = [NSString stringWithFormat:#"%#",str];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:urlString]];
[request setHTTPMethod:#"POST"];
NSMutableData *body = [NSMutableData data];
NSString *boundary = #"---------------------------14737809831466499882746641449";
NSString *contentType = [NSString stringWithFormat:#"multipart/form-data; boundary=%#",boundary];
[request addValue:contentType forHTTPHeaderField: #"Content-Type"];
[body appendData:[[NSString stringWithFormat:#"--%#\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[#"Content-Disposition: form-data; name=\"file\"; filename=\"a.jpg\"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[#"Content-Type: application/octet-stream\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[NSData dataWithData:imgData]];
[body appendData:[#"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
// parameter UserId
[body appendData:[[NSString stringWithFormat:#"--%#\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:#"Content-Disposition: form-data; name=\"userid\"\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[appDelegate.strUserID dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[#"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
// close form
[body appendData:[[NSString stringWithFormat:#"--%#--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
// setting the body of the post to the request
[request setHTTPBody:body];
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
// NSString *returnString = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];
NSDictionary *dict=[NSJSONSerialization JSONObjectWithData:returnData options:NSJSONReadingMutableLeaves error:nil];
NSLog(#"%#",dict);
I see that you send multiple files in one request, correct?
From HTTP specification, you should use multipart/mixed Content-type inside embedding multipart/form-data
Example from link above:
Content-type: multipart/form-data, boundary=AaB03x
--AaB03x
content-disposition: form-data; name="field1"
Joe Blow
--AaB03x
content-disposition: form-data; name="pics"
Content-type: multipart/mixed, boundary=BbC04y
--BbC04y
Content-disposition: attachment; filename="file1.txt"
I am posting an image from my IPhone app to a php page on a website using the code in this answer to this question. Essentially the code creates the correctly formatted html stream and submits it.
For Completeness, I have reposted the code.
- (BOOL)uploadImage:(NSData *)imageData filename:(NSString *)filename{
NSString *urlString = #"http://www.yourdomainName.com/yourPHPPage.php";
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--%#\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]];
[request setHTTPBody:body];
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSString *returnString = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];
return ([returnString isEqualToString:#"OK"]);
}
However I'm not clever enough :( to figure out how to add a general purpose field value eg. I would like to add a Comment field to be submitted along with the image file.
Any suggestions on how I could modify that code to add a number of fields to the POST form.
Thank you.
Update: I can get it to work by modifying the URL I post to to include GET Parameters, but I would rather use all post params.
It's not too difficult. The general format of a multipart/form-data post is like this:
--boundary-string
Content-Disposition: form-data; name="field1"
value1
--boundary-string
Content-Disposition: form-data; name="field2"
value2
--boundary-string--
File uploads are a special case, but you already have that handled. To add another field, you just add another block. Something like this should do it:
NSMutableData *body = [NSMutableData data];
[body appendData:[[NSString stringWithFormat:#"\r\n--%#\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:#"Content-Disposition: form-data; name=\"Comment\"\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[comment dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:#"\r\n--%#\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:#"Content-Disposition: form-data; name=\"userfile\"; filename=\"%#\"\r\n",filename] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[#"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];
BTW, you pretty much never need to call NSString's stringWithString: method. If you need a copy, call copy, and otherwise just use the string you already have. NSMutableString's stringWithString: can be useful as an alternative to [[string mutableCopy] autorelease] though.
First of all you should use addValue:forHTTPHeaderField: method of NSMutableURLRequest object to add headers. For example
[request addValue:#"application/octet-stream" forHTTPHeaderField:#"Content-Type"];
[request addValue:[NSString stringWithFormat:#"form-data; name=\"userfile\"; filename=\"%#\"",filename] forHTTPHeaderField:#"Content-Disposition"];
...
For second in your code after all headers are set as I described above you should set POST data with code below.
NSMutableData *body = [[NSMutableData alloc] init];
[body appendData:[[NSString stringWithString:#"name=myimagename.png"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithString:#"&data="] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[NSData dataWithData:imageData]];
[body release];
[request setHTTPBody:body];
But it will work if and only if server supports such format (I mean data=image binary data&name=image name).
I would suggest to use ASIHttp. See ASIFormDataRequest
I'm trying to send a single image from my iPhone app to my Google App Engine Java server. On the server, I'm getting a FileUploadBase$InvalidContentTypeException, which is thrown when the request is not a multipart request. ServletFileUpload.isMultipartContent(req) is printing false. I'm trying to send an image, encoded as a jpeg, and a few other parameters, but im testing with just "name" and the image. There are a few fragmented sources of info online demonstrating how to take an image from the iPhone and post it to a GAE server. I'd like to document both ends of the process here.
Here's my objective-c code:
NSData *imageData = [NSData dataWithData: UIImageJPEGRepresentation(theImageView.image, 1.0f)];
NSURL *url = [NSURL URLWithString:#"http://myurl.com/myservlet"];
NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease];
[request setURL:url];
[request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];
[request setTimeoutInterval:60.0];
[request setHTTPMethod:#"POST"];
NSMutableData *body = [NSMutableData data];
[body appendData:[[NSString stringWithString:#"Content-Type: multipart/form-data; boundary=\"6G+f\"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:#"\r\n--%#\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithString:#"Content-Disposition: form-data; name=\"name\"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithString:#"whatever"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:#"\r\n--%#\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithString:#"Content-Disposition: form-data; name=\"myImage\" filename=\"ipodfile.jpeg\"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithString:#"Content-Type: image/jpeg\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:imageData];
[body appendData:[[NSString stringWithFormat:#"\r\n--%#\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[request setHTTPBody:body];
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSString *returnString = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];
NSLog(#"return %#",returnString);
I took most of the java code from here: How to upload and store an image with google app engine (java) . I'll post the complete solution once the objective-c problem is found. THANKS!!
Scrap all that code and start using ASIHTTPRequest for your http client needs. It's SO much easier and more powerful. I build highly server-interactive apps that include image uploads, and I haven't touched the native NSURLConnection interface in literally months.
That library has an ASIFormDataRequest object that handles all the fiddly little pieces of configuration for you. You literally load it up with data, fire it, and it works.
http://allseeing-i.com/ASIHTTPRequest/How-to-use