在使用 Amazon iOS SDK 的 swift iOS 应用程序中,如何为 AWSS3TransferUtility 下载操作设置自定义超时?
Posted
技术标签:
【中文标题】在使用 Amazon iOS SDK 的 swift iOS 应用程序中,如何为 AWSS3TransferUtility 下载操作设置自定义超时?【英文标题】:In a swift iOS application that uses the Amazon iOS SDK, how to set a custom timeout to a AWSS3TransferUtility download operation? 【发布时间】:2019-04-25 20:12:47 【问题描述】:我在 ios 12 的 swift 应用程序中使用 AWS SDK for iOS。我的应用程序必须列出 AWS S3 存储桶中的文件并下载其中一些文件。列表文件操作运行良好,我成功控制了它的超时。我没有成功完成下载任务。我的代码如下:
let credentialProvider = AWSCognitoCredentialsProvider(regionType: AWSRegionType.USEast1, identityPoolId: "<pool-id>")
let configuration = AWSServiceConfiguration(region: AWSRegionType.APSoutheast2, credentialsProvider: credentialProvider)
configuration?.timeoutIntervalForRequest = 30.0
configuration?.timeoutIntervalForResource = 86400
let transferUtilityConfiguration = AWSS3TransferUtilityConfiguration.init()
transferUtilityConfiguration.timeoutIntervalForResource = 86400
transferUtilityConfiguration.retryLimit = 1
AWSS3TransferUtility.register(with: configuration!, transferUtilityConfiguration: transferUtilityConfiguration, forKey: "com.mykey")
transferUtility = AWSS3TransferUtility.s3TransferUtility(forKey: "com.mykey")
let bucket = "com.mybucket"
transferUtility.configuration.maxRetryCount = 1
let urlForSavingFile = URL.init(fileURLWithPath: "")
transferUtility.download(to: urlForSavingFile, bucket: bucket, key: self.latestFileOnServer.key, expression: expression, completionHandler: self.completionHandler).continueWith (task) -> AnyObject? in
if let error = task.error
NSLog("Error: %@",error.localizedDescription);
DispatchQueue.main.async(execute:
statusLabel.text = "Failed"
)
if let _ = task.result
self.refDownloadTask = task.result
self.refDownloadTask?.setCompletionHandler(self.completionHandler!)
methodStart = Date.init()
let formatter = DateFormatter.init()
formatter.dateFormat = "dd' 'MMM' 'YYYY' - 'HH:mm:ss"
formatter.locale = Locale.init(identifier: "Europe / Rome")
let italyDate = formatter.string(from: methodStart)
print("Download started at \(italyDate)")
DispatchQueue.main.async(execute:
//statusLabel.text = "Downloading..."
)
NSLog("Download Starting!")
// Do something with uploadTask.
return nil;
如果我等待文件完成下载,则会正确调用完成处理程序,但如果我使用网络链接调节器关闭网络,则传输将永远挂起,并且永远不会调用完成处理程序。任何帮助深表感谢。谢谢
【问题讨论】:
在这里报告同样的问题。我的与上传有关,而不是下载,但似乎不遵守超时,如果达到超时,则永远不会调用完成处理程序。 您好,我提供了一个解决方案,感谢您的评论,请告诉我它是否适合您。谢谢 【参考方案1】:经过多次测试,我成功找到了解决方案,并使 SDK 尊重超时。在我的测试中,最初,我对命名约定有点困惑:
timeoutIntervalForResource
是传输可以花费的最长时间,无论成功/失败。这与 AWS 开发工具包开箱即用。
timeoutIntervalForRequest
是我们感兴趣的值。它是网络丢失后任务等待额外数据的时间间隔。它的计时器是从收到最后一个数据包开始安排的。正如您在问题和 cmets 中看到的那样,AWS SDK 似乎不尊重它。
此命名约定与 Apple Cocoa USURLSession 系列类相同。在我的研究过程中,我遇到了这个answer。对于将其配置实例化为后台配置的 URLSession,似乎这种行为一直存在。这不是不当行为,它只是 iOS 8 以来后台下载的新标准。
现在,解决方案。通过在 AWS SDK Objective-C 代码中进行调试(是的,他们提供了完整的代码),我找到了位置。如果你打开 AWSS3TransferUtility.m 文件,在第 400 行,你会发现,在这个方法中:
- (instancetype)initWithConfiguration:(AWSServiceConfiguration *)serviceConfiguration
transferUtilityConfiguration:(AWSS3TransferUtilityConfiguration *)transferUtilityConfiguration
identifier:(NSString *)identifier
completionHandler: (void (^)(NSError *_Nullable error)) completionHandler
那些陈述:
//Create the NS URL session
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:_sessionIdentifier];
configuration.allowsCellularAccess = serviceConfiguration.allowsCellularAccess;
configuration.timeoutIntervalForResource = transferUtilityConfiguration.timeoutIntervalForResource;
为了使它起作用,请将第一条语句替换为:
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
现在,在您的代码中:
let credentialProvider = AWSCognitoCredentialsProvider(regionType: AWSRegionType.USEast1, identityPoolId: "<pool-id>")
let configuration = AWSServiceConfiguration(region: AWSRegionType.APSoutheast2, credentialsProvider: credentialProvider)
configuration?.timeoutIntervalForRequest = 30.0
configuration?.timeoutIntervalForResource = 86400
SDK 将在网络丢失 30 秒后触发完成处理程序并返回 -1001 错误。
我只测试了传输实用程序下载任务,但它也应该适用于上传。 我知道这个解决方案不是防弹的,因为它没有考虑会话配置标识符,但我会继续努力。此外,该解决方案意味着更改 AWS 开发工具包代码,但只需要一行代码。更改只是使 AWSS3TransferUtility 创建标准 URLSessionConfigurations 而不是后台的。这可能还有其他副作用需要考虑。
【讨论】:
以上是关于在使用 Amazon iOS SDK 的 swift iOS 应用程序中,如何为 AWSS3TransferUtility 下载操作设置自定义超时?的主要内容,如果未能解决你的问题,请参考以下文章
是否可以使用 iOS SDK 更改 Amazon Cognito 中的用户名?
在iOS Swift中不使用AWS SDK在Amazon S3存储桶中上传的背景图像(背景模式)
在使用 Amazon iOS SDK 的 swift iOS 应用程序中,如何为 AWSS3TransferUtility 下载操作设置自定义超时?