2

I managed to send some string with image data to the server. However array which contains the images has more than 1 object. I can perfectly get the first image from server but rest seems to disappear. Is there any way to send multiple data files to server or is there anything wrong in my for loop to send the images ? Server side code seems to work fine since it gets the strings and the first image file so I think there must be something wrong in the objective-c part of my code.

NSString *urlString = @"http://www.somesite.com/cgi-bin/somefile.py";

NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:urlString]];
[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];

NSString *filenames = [NSString stringWithFormat:@"some string"]; //set name here
[body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"sessionString\"\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[filenames dataUsingEncoding:NSUTF8StringEncoding]];

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

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

for (int i = 0; i < [self.pagesArray count]; i++) {
    NSData* imageData = UIImagePNGRepresentation(self.pagesArray[i]);
    NSLog(@"added %i", i+1);
    [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"file_%i\"; filename=\".png\"\r\n", i + 1] dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[@"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];

[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSString *returnString = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];

NSLog(@"%@", returnString);
NSLog(@"finish");
3
  • By the way, rather than using file_%i for the field name, you can also use file[] and it will build arrays. It results in a slightly different structure (so server changes would be needed), but it feels more intuitive to me (rather than coming up with arbitrary field names). It's entirely a matter of personal preference, but just wanted to suggest the alternative. Commented Jan 8, 2014 at 18:41
  • I'd also heartily suggest, at a minimum, using sendAsynchronousRequest rather than sendSynchronousRequest (unless you're doing this on a background queue already). Commented Jan 8, 2014 at 18:41
  • Thanks Rob I changed it to Asynchronous. It worked better. Commented Jan 8, 2014 at 22:30

1 Answer 1

2

The problem is that multipart form elements are separated with

[NSString stringWithFormat:@"\r\n--%@\r\n",boundary]

But then terminated with

[NSString stringWithFormat:@"\r\n--%@--\r\n",boundary]

But you're inserting that termination boundary string at the end of each file. You want to change your code to do that only at the end. Thus:

NSMutableData *body = [NSMutableData data];

NSString *filenames = [NSString stringWithFormat:@"some string"]; //set name here
[body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"sessionString\"\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[filenames dataUsingEncoding:NSUTF8StringEncoding]];

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

for (int i = 0; i < [self.pagesArray count]; i++) {
    [body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
    NSData* imageData = UIImagePNGRepresentation(self.pagesArray[i]);
    NSLog(@"added %i", i+1);
    [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"file_%i\"; filename=\".png\"\r\n", i + 1] dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[@"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];
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks mate your suggestion worked. I also came up with a different approach based on your comment. I used Asynchronous and sent each picture with their sole request. It is faster now :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.