I'm sending a picture building an HTTP POST like this:
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:url]];
[request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];
[request setHTTPShouldHandleCookies:NO];
[request setTimeoutInterval:30];
[request setHTTPMethod:@"POST"];
NSString *boundary = @"801f6dd4cd17";
NSString *contentType = [NSString stringWithFormat:@"multipart/form-data;boundary=------------------------------%@", boundary];
NSMutableDictionary *headerFieldsDict = [[ NSMutableDictionary alloc] init];
[ headerFieldsDict setObject:contentType forKey:@"Content-Type"];
[request setAllHTTPHeaderFields:headerFieldsDict];
NSMutableData *body = [NSMutableData data];
//---------- FIRST IMG
UIImage* imgLittle = [realImgButton imageForState:UIControlStateNormal];//thumImg.image;
NSData *imageData = UIImageJPEGRepresentation(imgLittle, 1.0);
if (imageData) {
[body appendData:[[NSString stringWithFormat:@"------------------------------%@
", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"image\"; filename=\"img.jpg\"
"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithString:@"Content-Type: application/octet-stream
"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:imageData];
[body appendData:[[NSString stringWithFormat:@"
"] dataUsingEncoding:NSUTF8StringEncoding]];
}
[body appendData:[[NSString stringWithFormat:@"------------------------------%@--
", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[request setHTTPBody:body];
But the server refuse to upload the image (it give a software error, it seems that the HTTP post it's not well parsed), the only information that i have about the server is that this client code in php works well:
$data['file'] = "@".$file;
$header[] = "Expect: ";
print_r($data);
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header );
//curl_setopt($ch, CURLOPT_URL, 'http://xxxxxx:yyy/');
curl_setopt($ch, CURLOPT_ENCODING, 'gzip,deflate');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
$response = curl_exec($ch);
curl_close($ch);
$xml = simplexml_load_string($response);
$url = strip_tags($xml->dict->string[3]->asXML());
return $url;
Any ideas? or where am I wrong on the obj-c code? I try to analyze the HTTP post statement produced and it seems the same as the one produced by the php code.
You might want to go with -addValue:forHTTPHeaderField:
instead of doing this:
NSMutableDictionary *headerFieldsDict = [[ NSMutableDictionary alloc] init];
[ headerFieldsDict setObject:contentType forKey:@"Content-Type"];
[request setAllHTTPHeaderFields:headerFieldsDict];
All you really need to do is to add a single header to the request, but you're effectively wiping out any existing headers with the code above.
you can use ASIHTTPRequest framework: I one of my projects I use this to upload images on server:
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:yourURL];
[request addPostValue:NSString forKey:@"KEY"];
[request addPostValue:NSString forKey:@"KEY"];
... any post value you need
[request addData:image withFileName:[name of the file]
andContentType:@"image/jpeg" forKey:@"KEY"];
Hope this help :)
I am not positive what the problem with your code is, but I have two ideas:
I think you might need another at the end of your
Content-Disposition
, like so:
[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"image\"; filename=\"img.jpg\"
"] dataUsingEncoding:NSUTF8StringEncoding]];
Using UIImageJPEGRepresentation
and setting your content type to application/octet-stream
might be the issue. [NSData dataWithContentsOfFile:]
might be more appropriate for application/octet-stream
and image/jpeg
might be more appropriate for UIImageJPEGRepresentation
. This is just a guess though.
If you are really stumped, you could use AFNetworking (which is more up to date and lighter weight than ASIHTTPRequest). Or you could at least check out their code to see how they handle file uploads.
The code you posted looked familiar, so I checked an old app where I'd been POSTing images, and we obviously got the code from the same source (which I don't recall). Mine is almost identical, save for the boundary strings, and the fact that I took out the redundant [NSString stringWithFormat:]
[request setHTTPMethod:@"POST"];
NSString *boundary = @"0xKhTmLbOuNdArY";
NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",boundary];
[request addValue:contentType forHTTPHeaderField: @"Content-Type"];
NSMutableData *body = [NSMutableData data];
[body appendData:[[NSString stringWithFormat:@"--%@
",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[@"Content-Disposition: form-data; name=\"image\"; filename=\"image.jpg\"
" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[@"Content-Type: application/octet-stream
" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:myImageData];
[body appendData:[[NSString stringWithFormat:@"r
--%@--
",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[request setHTTPBody:body];
This code works fine for me, so assuming nothing is wrong with your image data, your boundary may be the place to look. My image data is also created from UIImageJPEGRepresentation