iOS image upload to AWS S3 Bucket very slow

时间:2018-02-03 08:41:29

标签: ios swift xcode amazon-s3 image-uploading

I am trying to upload images to an AWS S3 bucket from my iOS app using the AWS SDK. I use the following method to upload the image:

func uploadMedia(mediaData: Data, mediaID: String) {

        let credentialsProvider = AWSCognitoCredentialsProvider(regionType:.SomeRegion,
                                                                identityPoolId:"my identity pool ...")
        let configuration = AWSServiceConfiguration(region:.SomeRegion, credentialsProvider:credentialsProvider)
        AWSServiceManager.default().defaultServiceConfiguration = configuration

        let transferManager = AWSS3TransferManager.default()

        let uploadingFileURL = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(mediaID)
        do {
            try mediaData.write(to: uploadingFileURL, options: Data.WritingOptions.atomic)
        } catch let error as NSError {
            print("Could not save \(error), \(error.userInfo)")
        }

        let uploadRequest = AWSS3TransferManagerUploadRequest()!

        uploadRequest.bucket = "myBucket"
        uploadRequest.key = mediaID + ".jpg"
        uploadRequest.body = uploadingFileURL
        uploadRequest.contentType = "image/jpeg"

        transferManager.upload(uploadRequest).continueWith(executor: AWSExecutor.mainThread(), block: { (task:AWSTask<AnyObject>) -> Any? in

            if let error = task.error as NSError? {
                if error.domain == AWSS3TransferManagerErrorDomain, let code = AWSS3TransferManagerErrorType(rawValue: error.code) {
                    switch code {
                    case .cancelled, .paused:
                        break
                    default:
                        print("Error uploading: \(uploadRequest.key!) Error: \(error)")
                    }
                } else {
                    print("Error uploading: \(uploadRequest.key!) Error: \(error)")
                }
                return nil
            }

            let uploadOutput = task.result
            print("Upload complete for: \(uploadRequest.key!)")
            return nil
        })
    }

The upload is successful but it takes significantly longer than just uploading via PHP script to a directory in my EC2 instance. Even for small files just 30 KB or so it takes a few seconds longer. I have turned off the default server encryption but that didn't help much.

Am I using the SDK correctly to upload the image data? The data is stored locally in coreData and extracted as Data rather than an image file. That's why I make a temporary directory to create the url for upload.

1 个答案:

答案 0 :(得分:1)

以下是基于sqlbot注释的代码:配置和传输管理器定义被移动到帮助程序类的初始化程序。如果图片文件存储在文档文件系统中,那么创建临时文件也不需要获得进一步的优势,但是我使用coreData所以需要保留它。

在viewController的早期初始化MediaHelper的一个实例(让mediaHelper = MediaHelper()),并保持对它的引用,以便在早期只进行一次初始化。

class MediaHelper {

    var transferManager: AWSS3TransferManager!

    init() {
        let credentialsProvider = AWSCognitoCredentialsProvider(regionType:.SomeRegion,
                                                                identityPoolId:"my identity pool ...")
        let configuration = AWSServiceConfiguration(region:.SomeRegion, credentialsProvider:credentialsProvider)
        AWSServiceManager.default().defaultServiceConfiguration = configuration

        self.transferManager = AWSS3TransferManager.default()
    }

    func uploadMedia(mediaData: Data, mediaID: String) {

        let uploadingFileURL = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(mediaID)
        do {
            try mediaData.write(to: uploadingFileURL, options: Data.WritingOptions.atomic)
        } catch let error as NSError {
            print("Could not save \(error), \(error.userInfo)")
        }

        let uploadRequest = AWSS3TransferManagerUploadRequest()!

        uploadRequest.bucket = "myBucket"
        uploadRequest.key = mediaID + ".jpg"
        uploadRequest.body = uploadingFileURL
        uploadRequest.contentType = "image/jpeg"

        transferManager.upload(uploadRequest).continueWith(executor: AWSExecutor.mainThread(), block: { (task:AWSTask<AnyObject>) -> Any? in

            if let error = task.error as NSError? {
                if error.domain == AWSS3TransferManagerErrorDomain, let code = AWSS3TransferManagerErrorType(rawValue: error.code) {
                    switch code {
                    case .cancelled, .paused:
                        break
                    default:
                        print("Error uploading: \(uploadRequest.key!) Error: \(error)")
                    }
                } else {
                    print("Error uploading: \(uploadRequest.key!) Error: \(error)")
                }
                return nil
            }

            let uploadOutput = task.result
            print("Upload complete for: \(uploadRequest.key!)")
            return nil
        })
    }

}