views:

111

answers:

3

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?

+2  A: 

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

Gubb
+1  A: 

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.

Dan Ray
Thanks for your quick reply. But I cant use a third part library like ASIHttpRequest in my project.
Aravind
Why's that? Is this a school assignment or something? Real developers reuse code.
Dan Ray
A: 
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:@"[email protected]"]; //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];
pradeepa