Pass parameters to web-service with image uploading in iphone

When you upload a file you are really posting a form's content to the browser by using a different encoding type (enctype) in your form. That encoding is specified as enctype="multipart/form-data" as an attribute of your form.
The specification in RFC 1867 "Form-based File Upload in HTML" describes the mechanism by which a file may be uploaded from a Web browser to the server.
There are a lot of articles to pass image to webservice. but, I require to pass some parameters with image.

Suppose I need to pass following parameters with image:
Parameter1
tag
status
customerID
customerName

Then following should be posted:


-----------------------------14737809831466499882746641449
Content-Disposition: form-data; name="parameter1"

MyValue1
-----------------------------14737809831466499882746641449
Content-Disposition: form-data; name="tag"

MyTags
-----------------------------14737809831466499882746641449
Content-Disposition: form-data; name="status"

1
-----------------------------14737809831466499882746641449
Content-Disposition: form-data; name="customerID"

B115B57A-23D3-56BC-B457-860BFDA83AB3
-----------------------------14737809831466499882746641449
Content-Disposition: form-data; name="customerName"

MyName 007
-----------------------------14737809831466499882746641449
Content-Disposition: form-data; name="image"; filename="20091228144754.jpg"
Content-Type: application/octet-stream

(Binary Content)
-----------------------------14737809831466499882746641449--


Format:
For normal input:

<hex value>CRLFContent-Disposition: form-data; name="<input
name>"CRLFCRLF<input value>CRLF


For file type input:

<hex value>CRLFContent-Disposition: form-data; name="<input
name>"; filename="<file
path>"CRLFContent-Type: <mime-type>CRLFCRLF<input
value>CRLF


iPhone Implementation:
We will pass the parameters in the above format. For this:
1. All the text like -----------------------------14737809831466499882746641449 is what separates each input.
2. Note also that in the end of the post we also have the text -----------------------------14737809831466499882746641449-- but it signals the end of our post, since it ends with 2 minus signs (--). Anyway, don't forget that this strange.
// setting up the request object now
 NSURL *nsurl =[NSURL URLWithString:urlString];
 NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:nsurl cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0]; 
 [request setURL:nsurl];
 [request setHTTPMethod:@"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];
 
 //parameter1
 [body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]]; 
 [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"parameter1\"\r\n\r\n%@", parameter1] dataUsingEncoding:NSUTF8StringEncoding]];
 [body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
 //Tags
 [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"tag\"\r\n\r\n%@", tag] dataUsingEncoding:NSUTF8StringEncoding]];
 [body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
 //Status
 [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"status\"\r\n\r\n%@", status] dataUsingEncoding:NSUTF8StringEncoding]];
 [body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
 //customerID
 [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"customerID\"\r\n\r\n%@", customerID] dataUsingEncoding:NSUTF8StringEncoding]];
 [body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
 //customerName
 [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"customerName\"\r\n\r\n%@", customerName] dataUsingEncoding:NSUTF8StringEncoding]];
 [body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
 //Image
 [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"image\"; filename=\"%@\"\r\n",[fileName text]] 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];
 
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
 
Hope, It helps.

3 comments:

  1. Hello,

    would using this method also pass the original EXIF information on the image( such as geographical location etc) to the image stored on the server

    ReplyDelete
  2. Thanks for the post. The idea is helpful, even though the code could use some polish...

    It would be much cleaner to build up the HTTP body an NSMutableString using the -appendString: and -appendFormat: methods, then convert with -dataUsingEncoding: only when necessary (before appending the image data). Also, factoring out the common line boundary string (@"\r\n--{boundary}") and the repeated Content-Disposition prefix (@"\r\nContent-Disposition: form-data; name=") instead of using +[NSString stringWithFormat:] every time would be faster and more elegant.

    ReplyDelete
  3. Hi Quinn, is it possible that you send me the above sample code with corrections you proposed. I couldn't do it myself from wht you said. I only need to post an image and text to an aspx page.
    Thanks for your help in advance.
    My email is: iboman at gmail dot com

    ReplyDelete