25

In my iOS app I want to upload file with the java API using NSMutableURLRequest for multipart file. here is the form which shows parameter.

  <form action="API_URL" encType='multipart/form-data' method=post>
            <input type=file name="files">
            <input type=submit value="Upload Attempt Files">

EDIT form2

       <form action='URL' method="post" encType='multipart/form-data'>
<input name="key1" value='123'>
<input name="key2" value='asdf'>
<input name="key3" value='qwerty'>
<input name="key4" value='aaa'>
<input name="key5" value='aaa'>
<input name="key6" value='false'>
<input type="file"  name="files">
<input type=submit value="Create Forum Posts">
   </form>        

How can I achieve that?

This Question shows how to upload multipart file using AFNetworking in iOS(objective c). But I am not getting how to put parameter as per form I am using.

halfer
  • 19,824
  • 17
  • 99
  • 186
ios
  • 6,134
  • 20
  • 71
  • 103
  • 1
    Do I correctly assume you want to do this upload via AFNetworking in Objective-C? (The reference to "Java API" is confusing, but I now assume you are just saying you're running some Java on the server. Is that right?) – Rob Mar 14 '13 at 14:21
  • Ok. The iOS app doesn't really care what technology the server's using behind the scenes, because it's communicating via HTTP and that's all we really care about here. The "java" tag and references in your question might send readers down the wrong path. You might want to remove those references... – Rob Mar 14 '13 at 15:31
  • Follow up question: Your HTML has button that says "Upload Attempt Files", and your `file` input field is called `files` (plural), but I assume you're only uploading one file at a time. My answer, below, works with the assumption that you're sending one file, but if there was something omitted from your question (for the sake of brevity) from the HTML snippet above that would otherwise permit multiple files to be specified, let me know. – Rob Mar 14 '13 at 15:32

3 Answers3

86

Looking at your HTML, the name of your <input type=file> is files, and thus, you would use @"files" as the name parameter to the appendPartWithFileData method. For example, with AFNetworking 3.x:

AFHTTPSessionManager *manager = [AFHTTPSessionManager 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"];

    [formData appendPartWithFormData:[key2 dataUsingEncoding:NSUTF8StringEncoding]
                                name:@"key2"];

    // etc.
} progress:nil success:^(NSURLSessionDataTask *task, id responseObject) {
    NSLog(@"Response: %@", responseObject);
} failure:^(NSURLSessionDataTask *task, NSError *error) {
    NSLog(@"Error: %@", error);
}];

(For AFNetworking 1.x and 2.x syntax, see the revision history of this answer.)

Rob
  • 415,655
  • 72
  • 787
  • 1,044
  • Thanks for help.... here how to send cookie data for authentication.. One more thing what ever request i am sending it is not visible at server what could be wrong... – ios Mar 15 '13 at 13:27
  • @ios Not sure re cookies, but perhaps [this answer](http://stackoverflow.com/questions/10984374/how-to-manage-sessions-with-afnetworking) helps. As to why is it not working, I can't say, because I tested it on my server and the file showed up fine. But if you need to cookie data for authentication and haven't done that, would you expect it to work? Regardless, perhaps edit your question, adding the latest rendition of your upload code. – Rob Mar 15 '13 at 13:32
  • @ios I assume you'd just add calls to [`appendPartWithFormData:name`](http://afnetworking.github.com/AFNetworking/Protocols/AFMultipartFormData.html#//api/name/appendPartWithFormData:name:) within that `multipartFormRequestWithMethod` block. – Rob Mar 18 '13 at 12:19
  • I tried that also NSMutableData *val4key1 =[[NSMutableData alloc] init]; [val4key1 appendData:[[NSString stringWithFormat:@"%@",mystring] dataUsingEncoding:NSUTF8StringEncoding]; [formData appendPartWithFormData:val4key1 name:@"key1"]; but it shows me error Invalid parameter not satisfying: body' what could be wrong – ios Mar 18 '13 at 13:00
  • 1
    @ios Yes, conceptually, though you could simplify to `[formData appendPartWithFormData:[mystring dataUsingEncoding:NSUTF8StringEncoding] name:@"key1"];` See revised answer. I've tested the above code and it seems to work with my server at least. Where are you seeing that error? – Rob Mar 18 '13 at 13:06
  • @Rob great answer you saved my time this answer works 100% just keep in mind the name declared in api or server of the variables use that only to append data . Keep it up!!! – Darshan Mothreja Apr 19 '16 at 11:28
5
-(void) makePhotoUploadRequest{

    NSArray *keys = [[NSArray alloc]initWithObjects:@"UserID", @"CompanyName" ,@"Location",@"Latitude",@"Longitude",@"Tagline",@"Goals",@"ColorName",nil];
    NSArray *values =[[NSArray alloc]initWithObjects:@"103",@"queppelin",@"Jaiur",@"11.3" ,@"12.3",@"Let's do it",@"Let's do it",@"Let's do it", nil];
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];

    NSURL *baseUrl = [NSURL URLWithString:[NSString stringWithFormat:@"%@%@/%@/RegisterCompanyUser",serverRequest,serverPort,serverName]];

    NSString *charset = (NSString *)CFStringConvertEncodingToIANACharSetName(CFStringConvertNSStringEncodingToEncoding(NSUTF8StringEncoding));
    [request setURL:baseUrl];
    [request setHTTPMethod:@"POST"];

   NSString *boundary = @"0xKhTmLbOuNdArY";
    NSString *endBoundary = [NSString stringWithFormat:@"\r\n--%@\r\n", boundary];

    NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; charset=%@; boundary=%@", charset, boundary];
    [request addValue:contentType forHTTPHeaderField: @"Content-Type"];

    NSMutableData *tempPostData = [NSMutableData data];
    [tempPostData appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];


           for(int i=0;i<keys.count;i++){
               NSString *str = values[i];
               NSString *key =keys[i];
               NSLog(@"Key Value pair: %@-%@",key,str);
               [tempPostData appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n", key] dataUsingEncoding:NSUTF8StringEncoding]];
               [tempPostData appendData:[str dataUsingEncoding:NSUTF8StringEncoding]];
              // [tempPostData appendData:[@"\r\n--%@\r\n",boundary dataUsingEncoding:NSUTF8StringEncoding]];
                   [tempPostData appendData:[endBoundary dataUsingEncoding:NSUTF8StringEncoding]];

        }





    // Sample file to send as data
    [tempPostData appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"Image\"; filename=\"%@\"\r\n", @"company-logo.png"] dataUsingEncoding:NSUTF8StringEncoding]];
    [tempPostData appendData:[[NSString stringWithString:@"Content-Type: application/octet-stream\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];

    UIImage *myImageObj = [UIImage imageNamed:@"company-logo.png"];
    NSData *mydata= UIImagePNGRepresentation(myImageObj);
    NSLog(@"Image data:%d",mydata.length);
        [tempPostData appendData:mydata];

    [tempPostData appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
    [request setHTTPBody:tempPostData];

    NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
    if( theConnection )
    {
       dataWebService = [NSMutableData data] ;
        NSLog(@"request uploading successful");
    }
    else
    {
        NSLog(@"theConnection is NULL");
    }


}
iphonic
  • 12,615
  • 7
  • 60
  • 107
Rahul
  • 172
  • 1
  • 4
0

You can use following code for send image and n number of parameter in multipart request using afnetworking 3.x

 AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
 //manager.responseSerializer = [AFHTTPResponseSerializer serializer]; // uncomment this line when the server is not returning JSON

[manager POST: urlString parameters: nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
    [formData appendPartWithFileData:imageData
                                name:@"file"
                            fileName:imageName mimeType:@"image/jpeg"];
        for (NSString *key in parameters) {
            [formData appendPartWithFormData:[[[parameters objectForKey:key] description] dataUsingEncoding:NSUTF8StringEncoding] name:key];
        }

    // etc.
} progress:nil success:^(NSURLSessionDataTask *task, id responseObject) {
    NSLog(@"Response: %@", responseObject);
} failure:^(NSURLSessionDataTask *task, NSError *error) {
    NSLog(@"Error: %@", error);
}];
Ruchin Somal
  • 1,073
  • 12
  • 14