Select and Upload Multiple Photos from Gallery or Camera in iOS

On December 4, 2015, in iPhone iPad Object-C, by James Liu

Select and upload photos is one of the most use cases in iPhone and iPad apps. Taking a picture and upload to your Facebook, or share it with your friends in Snapchat, it just looks very common. There are lots of iPhone apps which allow you to upload photos and write reviews. In return, you will get discount from your reviews. In this kind of iOS apps, selecting and uploading a single or multiple photos from gallery or camera become very necessary. In this tutorial, I will show you how to select photos in iPhone gallery, and upload the selected photos to server.

At the beginning, I will start the most simple case: select a single image from iPhone gallery, then upload it to the server. To make it working properly, I already create a PHP script which will accept the uploading request and save the uploaded photos on server. You can check the post: iOS Upload Image from Gallery or Camera to Server Side to get the server side source code.

Select Photos and Pictures from Gallery in iPhone

In iPhone, it already provides a very simple feature to help us select photo from it’s gallery. We can use UIImagePickerController and UIImagePickerControllerDelegate. The following example source code will open the gallery and let you to choose a image in iPhone.

simpleImagePicker = [[UIImagePickerController alloc] init];
simpleImagePicker.delegate = self;
[simpleImagePicker setSourceType:UIImagePickerControllerSourceTypePhotoLibrary];
[self presentViewController:simpleImagePicker animated:YES completion:nil];

The above source code will open the iPhone gallery and let us to select photos inside. Once we select one photo or picture, the following protocol function will be called in the UIImagePickerControllerDelegate.

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info {
    UIImage *image = [info valueForKey:UIImagePickerControllerOriginalImage];
    [previewImageView setImage: image];
    [simpleImagePicker dismissViewControllerAnimated:YES completion:nil];
}

The above example source code will get the selected photo in the gallery, and show the photo in UIImageView object, and close the photo selection view.

Upload Photo from iPhone Gallery By NSURLConnection

Just now, I demonstrate how to open an iPhone gallery and select photos inside. In this section, I will show you how to upload the selected photo to server. As usual, I will start from the simplest case, selecting and uploading one picture from iPhone gallery.

In most of the case, we will use NSURLConnection to communicate with server, in both “Get” and “Post” mode. However, this approach will be only available in older iOS than iOS 9.

To upload data to server by NSURLConnection, we shall use “POST” mode, just like website to submit data to server. I already wrote a tutorial about how to submit data and upload file to php server in website. In that tutorial, I give a HTML form example which can upload data and files to server. In iOS app, I will use NSMutableURLRequest to setup the http header and build http body to send the all data to PHP server. Now, let’s check how I implement this approach in objective-c.

- (void) uploadImageLegacy:(UIImage *)image {
    //upload single image
    NSURL *url = [NSURL URLWithString:@"http://127.0.0.1/uploadimage.php"];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:5.0];
    [request setHTTPMethod:@"POST"];
    NSString *contentTypeValue = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", POST_BODY_BOURDARY];
    [request addValue:contentTypeValue forHTTPHeaderField:@"Content-type"];
    
    NSMutableData *dataForm = [NSMutableData alloc];
    [dataForm appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",POST_BODY_BOURDARY] dataUsingEncoding:NSUTF8StringEncoding]];
    [dataForm appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"param1\";\r\n\r\n%@", @"10001"] dataUsingEncoding:NSUTF8StringEncoding]];
    
    NSData *imageData = UIImageJPEGRepresentation(image, 0.9);
    [dataForm appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",POST_BODY_BOURDARY] dataUsingEncoding:NSUTF8StringEncoding]];
    [dataForm appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"uploadFile\"; filename=\"%@.jpg\"\r\n", @"test"] dataUsingEncoding:NSUTF8StringEncoding]];
    [dataForm appendData:[[NSString stringWithFormat:@"Content-Type: image/jpeg\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
    [dataForm appendData:[NSData dataWithData:imageData]];
    
    [dataForm appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n",POST_BODY_BOURDARY] dataUsingEncoding:NSUTF8StringEncoding]];
    [request setHTTPBody:dataForm];
    [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES];
}

Upload Photo from iPhone Gallery By NSURLSession

To upload the selected image iOS 9, I will use NSURLSession. After iOS 9.0, Apple recommends to use NSURLSession, and many NSURLConnection methods will be deprecated after iOS 9. Therefore, in this tutorial, I will use NSURLSession instead of NSURLConnection. Please remember, NSURLSession is only supported after iOS 7.

NSURLSession Example: Upload Image to Server

Compare with NSURLConnection, NSURLSession is more powerful and provides us more API. As a beginner, NSURLSession looks like a container, which manages all request tasks. In NSURLSession, there are three tasks:

  • NSURLSessionDataTask: A task for retrieving the contents of a URL as an NSData object
  • NSURLSessionUploadTask: A task for uploading a file, then retrieving the contents of a URL as an NSData object
  • NSURLSessionDownloadTask: A task for retrieving the contents of a URL as a temporary file on disk

In our case, I will use NSURLSessionUploadTask to upload the file and get the response from the server. I will use following way to start the uploading task.

NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
        urlSession = [NSURLSession sessionWithConfiguration:sessionConfiguration delegate:self delegateQueue:nil];
NSURLSessionUploadTask *uploadTask = [urlSession uploadTaskWithRequest:request fromData:dataForm];
    [uploadTask resume];

One of the most powerful features of NSURLSession is we can watch the uploading progress and do some jobs before downloading the response. To implement all these features, we need to implement following delegates.

  • NSURLSessionDelegate
  • NSURLSessionTaskDelegate
  • NSURLSessionDataDelegate

And we have to implement following delegates methods.

  • – (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didSendBodyData:(int64_t)bytesSent totalBytesSent:(int64_t)totalBytesSent totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend
  • This method will be called first when we start to upload files or any type of data by NSURLSession. We can watch the uploading progress within this function. This method is included in NSURLSessionTaskDelegate.

  • – (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler
  • This method will be called once the client starts to receive data. We can implement completionHandler to control if we receive the data from server. This method is from NSURLSessionDataDelegate .

  • – (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
  • This method will be called when we receive the data from server. This method is from NSURLSessionDataDelegate .

  • – (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
  • This method will be called once the http request completes. This method is from NSURLSessionTaskDelegate.

Now I will show you how to implement above interface in real code. The following source code will be a good example for learning.

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didSendBodyData:(int64_t)bytesSent totalBytesSent:(int64_t)totalBytesSent totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend {
    NSLog(@"Sent %lld, Total sent %lld, Not Sent %lld", bytesSent, totalBytesSent, totalBytesExpectedToSend);
}

- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler {
    receiveData = [NSMutableData data];
    [receiveData setLength:0];
    completionHandler(NSURLSessionResponseAllow);
    NSLog(@"NSURLSession Starts to Receive Data");
}

- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data {
    [receiveData appendData:data];
    NSLog(@"NSURLSession Receive Data");
}

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
    NSLog(@"URL Session Complete: %@", task.response.description);
    
    if(error != nil) {
        NSLog(@"Error %@",[error userInfo]);
    } else {
        NSLog(@"Uploading is Succesfull");
        
        NSString *result = [[NSString alloc] initWithData:receiveData encoding:NSUTF8StringEncoding];
        NSLog(@"%@", result);
    }
}

Then, let’s check how the example looks like:

Select and Upload Multiple Images to Server

In above example source code, I just show you how to select one image and upload the selected image to server. After you understand the above source code, now it’s time for you to learn how to selected multiple images and upload them to the server all together.

iPhone only provides a simple user interface for you to select image, which I am using in my above example. To allow your user to select multiple photos in the user interface, you have to create your own. Fortunately, we can find a 3rd utility to implement this feature. ELCImagePicker, a simple but powerful library is created and displayed in a very similar manner to the UIImagePickerController. We can use this to allow for multiple photos selection.

Similar to UIImagePickerController, we can instantiate an ELCImagePickerController object and assign the ELCImagePickerControllerDelegate to this object. Here is the example source code:

imagePicker = [[ELCImagePickerController alloc] initImagePicker];
imagePicker.imagePickerDelegate = self;
[self presentViewController:imagePicker animated:YES completion:nil];

Here are the delegate methods which we need to implement:

- (void)elcImagePickerControllerDidCancel:(ELCImagePickerController *)picker {
    NSLog(@"Photos Canceled!");
}
- (void)elcImagePickerController:(ELCImagePickerController *)picker didFinishPickingMediaWithInfo:(NSArray *)info {
    if([info count] > 0) {
        for (NSDictionary *imageInfo in info) {
            UIImage *image = [imageInfo valueForKey:UIImagePickerControllerOriginalImage];
            //do anything here
        }
    }
    [imagePicker dismissViewControllerAnimated:YES completion:nil];

In the delegate method, we can get all the select photos information and binary data. So in next step, we can build the http request body with these information and upload all selected photos in one shot.

Upload Several Photos in One Shot

In above, I am using ELCImagePickerController to select multiple images at once. Then, the delegate method will return all selected image data, so that we can upload all the photos with this data. Actually, uploading multiple images is almost the same as uploading single image. The only different is passing more image data in the request data. Here I will only show you the NSURLSession example to upload multiple images to server.

- (void)elcImagePickerController:(ELCImagePickerController *)picker didFinishPickingMediaWithInfo:(NSArray *)info {
    
    NSURL *url = [NSURL URLWithString:@"http://127.0.0.1/uploadimage.php"];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:5.0];
    [request setHTTPMethod:@"POST"];
    NSString *contentTypeValue = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", POST_BODY_BOURDARY];
    [request addValue:contentTypeValue forHTTPHeaderField:@"Content-type"];
    
    NSMutableData *dataForm = [NSMutableData alloc];
    [dataForm appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",POST_BODY_BOURDARY] dataUsingEncoding:NSUTF8StringEncoding]];
    [dataForm appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"param1\";\r\n\r\n%@", @"10001"] dataUsingEncoding:NSUTF8StringEncoding]];
    
    if([info count] > 0) {
        int i = 0;
        for (NSDictionary *imageInfo in info) {
            UIImage *image = [imageInfo valueForKey:UIImagePickerControllerOriginalImage];
            image = [self resizeImage:image minSize:700.0];
            NSData *imageData = UIImageJPEGRepresentation(image, 0.9);
            [dataForm appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",POST_BODY_BOURDARY] dataUsingEncoding:NSUTF8StringEncoding]];
            [dataForm appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"fileToUpload[]\"; filename=\"%@%d.jpg\"\r\n", @"test", i] dataUsingEncoding:NSUTF8StringEncoding]];
            [dataForm appendData:[[NSString stringWithFormat:@"Content-Type: image/jpeg\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
            [dataForm appendData:[NSData dataWithData:imageData]];
            i++;
        }
    }
    
    [dataForm appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n",POST_BODY_BOURDARY] dataUsingEncoding:NSUTF8StringEncoding]];
    
    NSURLSessionUploadTask *uploadTask = [urlSession uploadTaskWithRequest:request fromData:dataForm];
    [uploadTask resume];
}

How to Use Source Code

This tutorial is for uploading photos in iPhone. To test this source code, you need to have a server to accept the uploading request. You can get the source code from iOS Upload Image Server Side Source Code.

Get Full Source Code Under $1.99

You can get the full source code at $1.99. It is a small money to support me continuing writing tutorials. You have the full permission to use the source code.

 

Comments are closed.

WordPress Themes