Select Image with UIImagePickerController and Upload to AWS S3 Bucket

This Swift code example will demonstrate how user UIImagePickerController to let user select image from their iPhone photo library and then upload selected image to Amazon AWS S3 Bucket.

The code example below will cover:

  • Set up AWS S3 Bucket policy,
  • Use UIImagePickerController to select image,
  • Display selected image as a subview
  • Use PHAsset to read selected image name,
  • Configure AWSCognitoCredentialsProvider,
  • Set up AWSS3TransferManagerUploadRequest
  • User AWSS3TransferManager to upload image
  • User UIAlertController to display alert message when image upload completes

AWS Bucket Policy

 "Version": "2008-10-17",
 "Statement": [
   "Sid": "AddPerm",
   "Effect": "Allow",
   "Principal": "*",
   "Action": "s3:GetObject",
   "Resource": "arn:aws:s3:::learn-swift/*"


Image Upload to Amazon AWS S3 Bucket. Complete Code Example in Swift.

import UIKit
import AWSCore
import AWSS3
import Photos

class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
    var showImagePickerButton: UIButton!
    var myImageView: UIImageView!
    var selectedImageUrl: NSURL!
    var myActivityIndicator: UIActivityIndicatorView!
    override func viewDidLoad() {
        // Do any additional setup after loading the view, typically from a nib.
    override func didReceiveMemoryWarning() {
        // Dispose of any resources that can be recreated.
    override func viewWillAppear(animated: Bool) {

    func startUploadingImage()
        var localFileName:String?

        if let imageToUploadUrl = selectedImageUrl
            let phResult = PHAsset.fetchAssetsWithALAssetURLs([imageToUploadUrl], options: nil)
            localFileName = phResult.firstObject?.filename
        if localFileName == nil
        // Configure AWS Cognito Credentials
        let myIdentityPoolId = ""
        let credentialsProvider:AWSCognitoCredentialsProvider = AWSCognitoCredentialsProvider(regionType:AWSRegionType.-- USEast1, identityPoolId: myIdentityPoolId)
        let configuration = AWSServiceConfiguration(region:AWSRegionType.-- USEast1, credentialsProvider:credentialsProvider)
        AWSServiceManager.defaultServiceManager().defaultServiceConfiguration = configuration
        // Set up AWS Transfer Manager Request
        let S3BucketName = "learn-swift"
        let remoteName = localFileName!
        let uploadRequest = AWSS3TransferManagerUploadRequest()
        uploadRequest.body = generateImageUrl(remoteName)
        uploadRequest.key = remoteName
        uploadRequest.bucket = S3BucketName
        uploadRequest.contentType = "image/jpeg"
        let transferManager = AWSS3TransferManager.defaultS3TransferManager()
        // Perform file upload
        transferManager.upload(uploadRequest).continueWithBlock { (task) -> AnyObject! in
            dispatch_async(dispatch_get_main_queue()) {
            if let error = task.error {
                print("Upload failed with error: (\(error.localizedDescription))")
            if let exception = task.exception {
                print("Upload failed with exception (\(exception))")
            if task.result != nil {
                let s3URL = NSURL(string: "\(S3BucketName)/\(uploadRequest.key!)")!
                print("Uploaded to:\n\(s3URL)")

                // Remove locally stored file
                 dispatch_async(dispatch_get_main_queue()) {
            else {
                print("Unexpected empty result.")
            return nil

    func displayAlertMessage()
        let alertController = UIAlertController(title: "Alert title", message: "Image has been uploaded", preferredStyle: .Alert)
        let OKAction = UIAlertAction(title: "OK", style: .Default) { (action:UIAlertAction!) in
            // Code in this block will trigger when OK button tapped.
            print("Ok button tapped");
        self.presentViewController(alertController, animated: true, completion:nil)
    func generateImageUrl(fileName: String) -> NSURL
        let fileURL = NSURL(fileURLWithPath: NSTemporaryDirectory().stringByAppendingString(fileName))
        let data = UIImageJPEGRepresentation(myImageView.image!, 0.6)
        data!.writeToURL(fileURL, atomically: true)
        return fileURL
    func remoteImageWithUrl(fileName: String)
        let fileURL = NSURL(fileURLWithPath: NSTemporaryDirectory().stringByAppendingString(fileName))
        do {
            try NSFileManager.defaultManager().removeItemAtURL(fileURL)
        } catch
    func setupImagePickerButton()
        let button = UIButton(type: UIButtonType.System) as UIButton
        let xPostion:CGFloat = 50
        let yPostion:CGFloat = 100
        let buttonWidth:CGFloat = 150
        let buttonHeight:CGFloat = 45
        button.frame = CGRectMake(xPostion, yPostion, buttonWidth, buttonHeight)
        button.backgroundColor = UIColor.lightGrayColor()
        button.setTitle("Select image", forState: UIControlState.Normal)
        button.tintColor = UIColor.blackColor()
        button.addTarget(self, action: #selector(ViewController.displayImagePickerButtonTapped) , forControlEvents: .TouchUpInside)
    func setupImageView()
        myImageView = UIImageView()
        let xPostion:CGFloat = 50
        let yPostion:CGFloat = 200
        let buttonWidth:CGFloat = 200
        let buttonHeight:CGFloat = 200
        myImageView.frame = CGRectMake(xPostion, yPostion, buttonWidth, buttonHeight)
    func setupUploadButton()
        let rightBarButton = UIBarButtonItem(title: "Upload", style: UIBarButtonItemStyle.Plain, target: self, action: #selector(ViewController.startUploadingImage))
        self.navigationItem.rightBarButtonItem = rightBarButton
    func setUpActivityIndicator()
        //Create Activity Indicator
        myActivityIndicator = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.Gray)
        // Position Activity Indicator in the center of the main view =
        // If needed, you can prevent Acivity Indicator from hiding when stopAnimating() is called
        myActivityIndicator.hidesWhenStopped = true
        myActivityIndicator.backgroundColor = UIColor.whiteColor()
    func displayImagePickerButtonTapped() {
        let myPickerController = UIImagePickerController()
        myPickerController.delegate = self;
        myPickerController.sourceType = UIImagePickerControllerSourceType.PhotoLibrary
        self.presentViewController(myPickerController, animated: true, completion: nil)
    func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject])
        selectedImageUrl = info[UIImagePickerControllerReferenceURL] as! NSURL

        myImageView.image = info[UIImagePickerControllerOriginalImage] as? UIImage
        myImageView.backgroundColor = UIColor.clearColor()
        myImageView.contentMode = UIViewContentMode.ScaleAspectFit
        self.dismissViewControllerAnimated(true, completion: nil)

Below is a link to a video tutorial which demonstrates how this code works as well as how to :

  • Create AWS S3 Bucket
  • Edit S3 Bucket policy to allow users read files from it
  • Use AWS Cognito to create a Federated Identity Pool
  • Install CocoaPods and use it to download AWS SDK for iOS
  • Write Swift code to upload image to AWS S3 Bucket

Upload Image to AWS S3 Bucket. In Swift.

Learn iOS Development with these Video Courses

How to Make a Freaking iPhone App - iOS 10 and Swift 3
icon icon

iOS 10 & Swift 3: From Beginner to Paid Professional

The Complete iOS 10 Developer Course - Build 21 Apps

Swift 3 - Learn to Code with Apple's New Language
icon icon

Learn How to Build Mobile Apps for iOS with Swift, PHP and MySQL
icon icon

Follow me on one of your favourite social networks to learn about new video tutorials and code examples:

Twitter: @SwiftVideoBlog
Google Plus:
Facebook: Swift Developer Blog on Facebook