How to upload images using swift 2: send multipart post request

In this new iOS 9 tutorial you'll see how to upload an image to a server with a multipart post request using swift 2. You'll see how to allow the picture selection from the device gallery using the UIIMagePickerController and how to define the callback delegate called as soon as the image has been selected. You'll learn then how to send the image through a post request with more post parameters

Configure the project

Let's start by opening Swift and by creating a new iOS single view app. In order to allow the http protocol in swift 2, you'll need to edit the info.plist file. Search for the info.plist file, right click on it, choose open as - source code and write the following lines:

<key>NSAppTransportSecurity</key>

<dict>

<key>NSAllowsArbitraryLoads</key>

<true/>

</dict>

Layout definition

Let's define now the Layout of the project. Open the main.storyboard and disable the use size classes feature, we don't require that.
Now let's add inside the ViewController two buttons and an ImageView, like the image below:

The Choose an image button will open the iOS Image Picker, the UIImageView will let us preview the selected image, while the Upload button will upload it on the server using a mutipart post request.

Let's now link, using the assistant editor, the inserted views to the variables. Click on the assistant editor, and drag and drop the elements inside the ViewController class by holding the CTRL button. Start from the Choose an image button and link it to an IBAction event. In this example I've called it selectPicture. Link now the Upload button to another IBAction event. I've called this upload_request. Finally link the ImageView as a simple UIImageView variable, I've called the variable image.

@IBOutlet var image: UIImageView!



@IBAction func selectPicture(sender: AnyObject) {

}



@IBAction func upload_request(sender: AnyObject) {

}

Implement the Image Picker and Image Picker delegate

Let's now implement the selectPicture function. This will call the UIImagePickerController and will define the UIImagePickerController delegate. This will define the callback class, called as soon as an image has been selected.

@IBAction func selectPicture(sender: AnyObject) {

let ImagePicker = UIImagePickerController()
ImagePicker.delegate = self
ImagePicker.sourceType = UIImagePickerControllerSourceType.PhotoLibrary

self.presentViewController(ImagePicker, animated: true, completion: nil)

}



func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {

image.image = info[UIImagePickerControllerOriginalImage] as? UIImage
self.dismissViewControllerAnimated(true, completion: nil)

}

Be also sure to add in the class definition the following classes:

class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {

Now the button choose an image will call the UIImagePickerController istance, and as soon as an image is selected, the imagePickerController callback is called. This function will display the selected image in the preview, and dismiss the UIImagePickerController view.

Upload the image on the server using the NSURLSession

It's now time to upload the image on the server. The upload_request method will call the UploadRequest function, that will then upload the choosed image. For this example I've prepared a simple php script. This script will just read the file field of the request and put back the file image name. We'll use the NSURLSession dataTaskWithRequest function.

func UploadRequest()
{
let url = NSURL(string: "http://www.kaleidosblog.com/tutorial/upload.php")

let request = NSMutableURLRequest(URL: url!)
request.HTTPMethod = "POST"

let boundary = generateBoundaryString()

//define the multipart request type

request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")

if (image.image == nil)
{
return
}

let image_data = UIImagePNGRepresentation(image.image!)


if(image_data == nil)
{
return
}


let body = NSMutableData()

let fname = "test.png"
let mimetype = "image/png"

//define the data post parameter

body.appendData("--\(boundary)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData("Content-Disposition:form-data; name=\"test\"\r\n\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData("hi\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)



body.appendData("--\(boundary)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData("Content-Disposition:form-data; name=\"file\"; filename=\"\(fname)\"\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData("Content-Type: \(mimetype)\r\n\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData(image_data!)
body.appendData("\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)


body.appendData("--\(boundary)--\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)



request.HTTPBody = body



let session = NSURLSession.sharedSession()


let task = session.dataTaskWithRequest(request) {
(
let data, let response, let error) in

guard let _:NSData = data, let _:NSURLResponse = response where error == nil else {
print("error")
return
}

let dataString = NSString(data: data!, encoding: NSUTF8StringEncoding)
print(dataString)

}

task.resume()


}


func generateBoundaryString() -> String
{
return "Boundary-\(NSUUID().UUIDString)"
}

In this example we'll send the file and an additional post parameter, called test in this case.

PHP script to store the image

<?php

if (move_uploaded_file($_FILES['file']['tmp_name'], "image.png")) {
echo "File uploaded: ".$_FILES["file"]["name"];
}

Here you'll find the project for this example: download.

UPDATED: Here you'll find the swift 3 project