首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在使用亚马逊iOS软件开发工具包的iOS应用程序中,如何设置AWSS3TransferUtility下载操作的自定义超时?

在使用亚马逊iOS软件开发工具包的iOS应用程序中,如何设置AWSS3TransferUtility下载操作的自定义超时?
EN

Stack Overflow用户
提问于 2019-04-26 04:12:47
回答 1查看 1K关注 0票数 1

我在一个适用于iOS 12的swift应用程序中使用AWS SDK for iOS。我的应用程序必须列出亚马逊网络服务S3存储桶中的文件,并下载其中一些文件。列出文件的操作运行良好,我成功地控制了它的超时。对于下载任务,我没有成功做到这一点。我的代码如下:

代码语言:javascript
复制
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;
        }

如果我等待文件完成下载,则正确地调用完成处理程序,但如果我使用网络链接调节器关闭网络,则传输将永远挂起,并且永远不会调用完成处理程序。任何帮助都是非常感谢的。谢谢

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-04-28 06:07:45

经过几次测试,我成功地找到了解决方案,并使SDK遵守超时。在我的测试中,最初,我对命名约定感到有点困惑:

timeoutIntervalForResource是传输可以花费的最长时间,无论是否成功/失败。这可以通过AWS SDK开箱即用。

timeoutIntervalForRequest是我们感兴趣的值。它是任务在网络丢失后等待额外数据的时间间隔。它的计时器是从最后一个接收到的数据包开始调度的。正如您在问题和评论中看到的那样,AWS SDK似乎没有遵守这一点。

此命名约定与Apple Cocoa USURLSession类家族相同。在我的研究过程中,我偶然发现了这个answer。对于将其配置实例化为后台配置的URLSessions,似乎已经一致地经历了这种行为。这不是一种不当行为,它只是从iOS 8开始的后台下载的新标准。

现在,解决方案。通过在AWS SDK Objective-C代码中进行调试(是的,他们提供了完整的代码),我找到了要点。如果您打开AWSS3TransferUtility.m文件,在大约400行,您将在此方法中找到:

代码语言:javascript
复制
- (instancetype)initWithConfiguration:(AWSServiceConfiguration *)serviceConfiguration
     transferUtilityConfiguration:(AWSS3TransferUtilityConfiguration *)transferUtilityConfiguration
                       identifier:(NSString *)identifier
                completionHandler: (void (^)(NSError *_Nullable error)) completionHandler {}

这些声明:

代码语言:javascript
复制
//Create the NS URL session
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:_sessionIdentifier];
configuration.allowsCellularAccess = serviceConfiguration.allowsCellularAccess;
configuration.timeoutIntervalForResource = transferUtilityConfiguration.timeoutIntervalForResource;

要使其正常工作,请将第一条语句替换为:

代码语言:javascript
复制
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];

现在,在你的代码中:

代码语言:javascript
复制
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 SDK代码,但只需更改一行代码。这一更改只是让AWSS3TransferUtility创建标准URLSessionConfigurations,而不是后台The。这可能还有其他要考虑的副作用。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55856944

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档