我一直在试图弄清楚如何从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逻辑/语法。我感谢任何帮助/建议,谢谢!