Joseph Astrahan
Joseph Astrahan

Reputation: 9072

Show Upload Progress for Image Upload to Amazon S3 using Swift 3 and Amazon SDK

I am able to successfully upload an image to Amazon S3, but I can't seem to figure out how to show the progress of it doing so.

I'm currently uploading like so.

import UIKit
import MapKit
import CoreData
import AWSCore
import AWSCognito
import AWSS3
import MobileCoreServices
import AWSMobileAnalytics

in my upload button I have the following code...

let myIdentityPoolId = "us-west-2:dca2beb4-9a67-etc....etc..."
                let credentialsProvider:AWSCognitoCredentialsProvider = AWSCognitoCredentialsProvider(regionType: AWSRegionType.usWest2, identityPoolId: myIdentityPoolId)
                let configuration = AWSServiceConfiguration(region: AWSRegionType.usWest2, credentialsProvider: credentialsProvider)
                AWSServiceManager.default().defaultServiceConfiguration = configuration

self.uploadImage(filename)

This is the uploadImage function...

func uploadImage(filename:String){
        print("AWS Upload Image Attempt...")
        //defining bucket and upload file name
        let S3BucketName: String = "distribution-tech-mobile-live"
        let filepath = "\(AppDelegate.appDelegate.applicationDocumentsDirectory())/\(filename)"
        let imageURL = URL(fileURLWithPath: filepath)
        let S3UploadKeyName = filename //TODO: Change this later

        let uploadRequest = AWSS3TransferManagerUploadRequest()
        uploadRequest?.bucket = S3BucketName
        uploadRequest?.key = filename
        uploadRequest?.contentType = "image/jpeg"
        uploadRequest?.body = imageURL
        uploadRequest?.serverSideEncryption = AWSS3ServerSideEncryption.awsKms
        uploadRequest?.uploadProgress = { (bytesSent, totalBytesSent, totalBytesExpectedToSend) -> Void in
            DispatchQueue.main.async(execute: {
                self.amountUploaded = totalBytesSent // To show the updating data status in label.
                self.fileSize = totalBytesExpectedToSend
                print("\(totalBytesSent)/\(totalBytesExpectedToSend)")
            })
        }

        self.uploadCompletionHandler = { (task, error) -> Void in
            DispatchQueue.main.async(execute: {
                if ((error) != nil){
                    print("Failed with error")
                    print("Error: \(error!)");
                }
                else{
                    print("Sucess")
                }
            })
        }

        let transferUtility = AWSS3TransferUtility.default()
        let expression = AWSS3TransferUtilityUploadExpression()

        transferUtility.uploadFile(imageURL, bucket: S3BucketName, key: S3UploadKeyName, contentType: "image/jpeg", expression: expression, completionHander: uploadCompletionHandler).continue({ (task) -> AnyObject! in
            if let error = task.error {
                print("Error: \(error.localizedDescription)")
            }
            if let exception = task.exception {
                print("Exception: \(exception.description)")
            }
            if let _ = task.result {
                print("Upload Starting!")
            }

            return nil;
        })

    }

I got the code for image uploading progress from another thread but there solution doesn't seem to work or I'm misunderstanding it.

Upload image AWS S3 bucket in swift, and this thread (Swift - AWS S3 Upload Image from Photo Library and download it). They both have 2 different ways to do it, the last link I couldn't get its way to work either.

I'm not sure what I'm doing wrong.

Upvotes: 3

Views: 3166

Answers (1)

Joseph Astrahan
Joseph Astrahan

Reputation: 9072

Okay I found the solution to my problem, apparently I just didn't follow through enough.

Here is my new revised uploadImage function

func uploadImage(filename:String){
        print("AWS Upload Image Attempt...")
        //defining bucket and upload file name
        let S3BucketName: String = "distribution-tech-mobile-live"
        let filepath = "\(AppDelegate.appDelegate.applicationDocumentsDirectory())/\(filename)"
        let imageURL = URL(fileURLWithPath: filepath)
        let S3UploadKeyName = filename //TODO: Change this later

        let uploadRequest = AWSS3TransferManagerUploadRequest()
        uploadRequest?.bucket = S3BucketName
        uploadRequest?.key = S3UploadKeyName
        uploadRequest?.contentType = "image/jpeg"
        uploadRequest?.body = imageURL
        uploadRequest?.serverSideEncryption = AWSS3ServerSideEncryption.awsKms
        uploadRequest?.uploadProgress = { (bytesSent, totalBytesSent, totalBytesExpectedToSend) -> Void in
            DispatchQueue.main.async(execute: {
                self.amountUploaded = totalBytesSent // To show the updating data status in label.
                self.fileSize = totalBytesExpectedToSend
                print("\(totalBytesSent)/\(totalBytesExpectedToSend)")
            })
        }

        let transferManager = AWSS3TransferManager.default()
        transferManager?.upload(uploadRequest).continue(with: AWSExecutor.mainThread(), withSuccessBlock: { (taskk: AWSTask) -> Any? in
            if taskk.error != nil {
                // Error.
                print("error")
            } else {
                // Do something with your result.
                print("something with result when its done")
            }
            return nil
        })

    }

This has spot for when result is done and during the upload progress and makes a lot more sense.

Upvotes: 4

Related Questions