AWS S3上载的Swift异步请求重试

时间:2018-02-09 01:57:02

标签: swift asynchronous amazon-s3

我一直在试图弄清楚如何从Swift上传多个文件(图像)到AWS S3。我问过上一个问题here,但未收到任何回复。而不是尝试&再次问同样的问题,我希望找到关于为一个触发网络请求w /完成处理程序的函数创建重试函数/包装器的指导。我发现了这个问题here&我试图对它进行类似的建模。 Cristik&答案的答案JustinM是用Swift 3编写的,所以当试图用Swift 4编写它们时,我不得不做一些改动。可悲的是,我担心我在转换中失去了一些逻辑(我不完全理解他们建议的所有内容,因此我的一些更改只是Xcode的建议)。这是我从他们的问题和重构中重构的内容。实施AWS S3 Transfer Utility:

static func retryFunction(numberOfTimes: Int, task: @escaping (_ success: @ escaping (String) -> (), _ failure: @escaping (Error) -> ()) -> (), success: @escaping (String) -> (), failure: @escaping (Error) -> ()) {
    task({ (result) in
        success(result)
    }) { (error) in
        if numberOfTimes > 1 {
            print("retrying with \(numberOfTimes - 1)")
            self.retryFunction(numberOfTimes: numberOfTimes - 1, task: task, success: success, failure: failure)
        } else {
            failure(error)
        }
    }
}

static func singleImageUploadAttempt(_ dataToUpload: Data, _ imageKey: String,
                                     _ success: @escaping (String) -> (), _ failure: @escaping (Error) -> ()) {

    let expression = AWSS3TransferUtilityUploadExpression()
    var completionHandler: AWSS3TransferUtilityUploadCompletionHandlerBlock?
    let transferUtility = AWSS3TransferUtility.default()

    completionHandler = { (task, error) -> Void in
        if let error = error {
            print("failure to upload the image: \(imageKey)")
            failure(error)
        } else{
            print("\(imageKey) uploaded successfully")
            success(imageKey)
        }
    }

    transferUtility.uploadData(dataToUpload, bucket: s3BucketName, key: imageKey, contentType: "image/png",
                               expression: expression, completionHandler: completionHandler).continueWith { (task) -> AnyObject! in

                                if let error = task.error {
                                    print("An error occurred generating the task")
                                    failure(error)
                                }

                                return nil;
    }

}

static func uploadImages(imagesToUpload: [UIImage], complete: @escaping (String?) -> ()) {
    let folderKey = UUID().uuidString
    var retryArray = [String: Data]()
    let imageGroup = DispatchGroup()

    for i in 0..<imagesToUpload.count {
        let resizedImage = compressImage(imageToReduce: imagesToUpload[i], expectedSizeInMb: 2)
        let imageKey = "public/\(folderKey)/image\(i).png"
        let imageData = UIImagePNGRepresentation(resizedImage!)
        retryArray[imageKey] = imageData!

        imageGroup.enter()
        retryFunction(numberOfTimes: 3, task: { success, failure in singleImageUploadAttempt(imageData!, imageKey,
                                                                                             success, failure) },
            success: { (keyToRemove) in
                retryArray.removeValue(forKey: keyToRemove)
                print("updated")
                print("successfully uploaded \(imageKey)")
                imageGroup.leave()
            },
            failure: { (err) in
                print("failed to upload \(imageKey)")
                imageGroup.leave()
            }
        )
    }
    imageGroup.notify(queue: DispatchQueue.main) {
        if(retryArray.keys.count > 0) {
            print("the images could not be uploaded")
            complete(nil)
        } else {
            print("all images uploaded successfully")
            complete(folderKey)
        }
    }

}

现在,当我有连接时,图像上传工作正常。然而,当我尝试没有连接时,该函数只是无限地等待。它为每个图像调用singleImageUploadAttempt,但没有命中完成处理程序或task.error。我的所有打印语句都没有被触发,而不是每个图像击中该函数3次(3次重试),它命中imageGroup.notify()然后什么都不做。如果我错过任何一个,我道歉 - 我仍然试图理解所有这些Swift逻辑/语法。我感谢任何帮助/建议,谢谢!

0 个答案:

没有答案