Uploading file in iOS

Multipart form data and HTTP (body content) are most popular ways to upload files. In iOS, using AFNetworking 2.0, it is very easy to manage. Let’s jump:

1) Using multipart form data to form request:

    NSString *path = [[NSBundle mainBundle] pathForResource:@"MyFileToUpload" ofType:@"jpg"];
    
    NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:@"POST" URLString:@"http://harit.kotharee.com/uploadMyImageMultipart.php" parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData)
    {
        [formData appendPartWithFileURL:[NSURL fileURLWithPath:path] name:@"file" fileName:@"MyFileToUpload.jpg" mimeType:@"image/jpeg" error:nil];
    } error:nil];

2) Using HTTP POST to form request – here in this case A JSON request

    NSString *fileName = @"MyFileToUpload.jpg";
    UIImage *newImage = [UIImage imageNamed:fileName];
    NSData *data = UIImageJPEGRepresentation (newImage, 1.0f);
    
    NSString *strEncoded;
    if ([data respondsToSelector:@selector(base64EncodedStringWithOptions:)])
    {
        strEncoded = [data base64EncodedStringWithOptions:kNilOptions];  // iOS 7+
    }
    else
    {
        strEncoded = [data base64Encoding];        // pre iOS7
    }
    
    // have your own JSON or other format of request
    NSString *jsonRequest = [[NSString alloc] initWithFormat:@"{\"FileName\":\"%@\",\"ImageContent\":\"%@\"}", fileName, strEncoded];
    
    NSURL *url = [NSURL URLWithString:@"http://harit.kotharee.com/uploadMyImageHTTPbody"];
    
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
    NSInputStream *imageStream = [[NSInputStream alloc] initWithData:[jsonRequest dataUsingEncoding:NSUTF8StringEncoding]];
    
    [request setHTTPMethod:@"POST"];
    [request setValue:@"application/json" forHTTPHeaderField:@"Accept"];
    [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
    // This is key part, instead of appending NSData, use stream when you expect the data to be larger
    [request setHTTPBodyStream:imageStream];

That’s pretty much done. Rest is simple and common for both ways:

    // handling operation response
    AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
    [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject)
    {
        NSLog(@"Cool! Let's proceed!");
    }
    failure:^(AFHTTPRequestOperation *operation, NSError *error)
    {
        NSLog(@"Oops! Handle gracefully!");
    }];
    
    [operation start];

In case of multipart request, we need to pass absolute URL of file. Of course, we can get it for bundle as well as camera roll. The deal with multipart request is that actual content of file is not loaded on iOS as data objects at runtime. Rather, HTTP (protocol) handles the it (add breakpoint at line #5 in [1] and debug!), so is a nice and probably best way to use for large size data, without worrying about memory issues.

Leave a Comment


NOTE - You can use these HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

%d bloggers like this: