ShahiM
ShahiM

Reputation: 3268

HTTP Multipart request in Obj-C

Prologue

So I'm making the iOS version of an android app. all the webservices are already setup but they dont have much detailed documentation, so I choose to go with inferring that from the android code. The project is complete except for one small thing - A HTTP Multipart request.

What I Need

I need to implement a web-request from java into objective-c. What this does is upload an image along with the user ID to the server and obtains a response. Here is the relevant Java code :

HttpClient httpClient = new DefaultHttpClient();
HttpPost postRequest=new HttpPost(Constant.server_url+"usermain/Profileimagesave");
String fileName = String.format("File_%d.png",new Date().getTime());
ByteArrayBody bab = new ByteArrayBody(data, fileName);
            
MultipartEntity reqEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
reqEntity.addPart("file", bab);
reqEntity.addPart("WebID", new StringBody(SharedPreferenceSession.getValue(getApplicationContext(), "WebId")));
postRequest.setEntity(reqEntity);

What I Tried

I have been trying for almost a week to mimic this code into objective-c. Here's what I could manage after taking in stefan's answer:

[manager POST:urlstr parameters:nil
constructingBodyWithBlock:^(id<AFMultipartFormData> formData){
  [formData appendPartWithFileData:imageData
                              name:@"blahblah.jpg"
                          fileName:@"blahblah.jpg"
                          mimeType:@"image/jpeg"];

  [formData appendPartWithFormData:[webid dataUsingEncoding:NSUTF8StringEncoding]
                              name:@"WebID"];
}
     progress:nil
      success:^(NSURLSessionTask *task, id responseObject) {
          NSLog(@"Response: %@", responseObject);
      }
      failure:^(NSURLSessionTask *operation, NSError *error) {
          NSLog(@"%@",[error.userInfo objectForKey:JSONResponseSerializerWithDataKey]);
}];

I have been trying a lot of variations of the above code, but as I dont have a clear understanding of a multipart request, I feel like I'm going around in circles.

what I got

I am getting a 500 error from the server.

PHP warning

copy(../UserData/ThumbPhotos/MOB274565CCM_20151230062220.): failed to open stream: No such file or directory

1773 $login1=$login->LoginID;
1774 $curr_date=date("YmdHis");
1775 $currentname=$webid."_".+$curr_date;
1776
1777 //echo "file size:".$_FILES['file']['size'];
1778 $info = pathinfo($_FILES['file']['name']);
1779 $ext=$info['extension'];
1780 $filename="{$currentname}.{$ext}";
1781 $sourcePath = $_FILES['file']['tmp_name'];
1782 $targetPath="../UserData/ThumbPhotos/".$filename;
1783 $targetPath1="../UserData/UserPhoto/".$filename;
1784 move_uploaded_file($sourcePath,$targetPath);

1785 copy($targetPath,$targetPath1);

1786 $userfiles=new UserFiles;
1787 $userfiles->LoginID=$login1;
1788 $userfiles->FileActualName=$filename;
1789 $userfiles->FileTempName=$filename;
1790 $userfiles->ThumbImage=$filename;
1791 $userfiles->Type="IMAGE";
1792 $userfiles->ProfileImage=0;
1793 $userfiles->deletedStatus=0;
1794 $userfiles->UploadBy=$login1;
1795 $userfiles->UploadDate=date("Y-m-d");
1796 $userfiles->deletedby=NULL;
1797 $userfiles->PasswordProtected=0;

What could help

I am not able to wrap my head around what is going on in the above code as I am not well versed with how HTTP requests function. So anything that can help me understand this is welcome, may it be a working code example, tips to debug the request or comments on how these things work.

or

The android code is working fine. So is there any way that I could inspect the outgoing request on both the android and iOS apps and maybe try to match them up by trial and error?

Thanks in advance

Upvotes: 0

Views: 570

Answers (2)

Stefan
Stefan

Reputation: 1335

I would like to suggest you to use AFNetworking. In this case, you want to upload some image, so I will give you code for that:

NSData *imageData = [NSData dataWithContentsOfFile:filename];
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];

[manager POST:urlString parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
    [formData appendPartWithFileData:imageData
                                name:@"files"
                            fileName:photoName mimeType:@"image/jpeg"];
[formData appendPartWithFormData:[key1 dataUsingEncoding:NSUTF8StringEncoding]
                            name:@"key1"];

} success:^(AFHTTPRequestOperation *operation, id responseObject) {
    NSLog(@"Response: %@", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    NSLog(@"Error: %@", error);
}];

Upvotes: 2

jigs
jigs

Reputation: 859

Try out this for upload any image using NSMutableURLRequest

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:YOUR_URL]];
[request setHTTPMethod:@"POST"];
NSString *boundary = @"---------------------------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 stringWithFormat:@"Content-Disposition: form-data; name=\"uploadfile\"; filename=\"%@.jpg\"\r\n", filename] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[@"Content-Type: application/octet-stream\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[NSData dataWithData:_YOUR_IMAGE_DATA]];

[body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"posttype\"\r\n\r\n%@", postType] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];

[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"postimgtext\"\r\n\r\n%@", postTextType] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];

[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"userid\"\r\n\r\n%@", USER_ID] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];

[request setHTTPBody:body];

NSError *error = nil;
NSURLResponse *response = nil;
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
if (!error) {
     NSString *response = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
     NSLog(@"response : %@", response);
}

Upvotes: 1

Related Questions