在使用Amazon iOS SDK的快速iOS应用程序中,如何为AWSS3TransferUtility下载操作设置自定义超时? [英] In a swift iOS application that uses the Amazon iOS SDK, how to set a custom timeout to a AWSS3TransferUtility download operation?

查看:151
本文介绍了在使用Amazon iOS SDK的快速iOS应用程序中,如何为AWSS3TransferUtility下载操作设置自定义超时?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在快速应用程序中使用适用于iOS的AWS开发工具包 iOS12.我的应用程序必须列出AWS S3存储桶中的文件并下载其中的一些文件.列表文件操作运行良好,我成功控制了它的超时.我没有成功完成下载任务.我的代码如下:

I am using the AWS SDK for iOS in a swift application for iOS 12. My app has to list files in a AWS S3 bucket and download some of them. The list files operation works well and I succeeded in having control of its timeout. I did not succeed to do that for the download task. My code is the following:

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;
        }

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

The completion handler is properly called if I wait for the file to finish downloading, but if I turn off the network with the network link conditioner the transfer hangs forever and the completion handler is never called. Any help is much appreciated. Thanks

推荐答案

经过几次测试,我成功找到了解决方案并使SDK遵守超时要求.最初,在测试过程中,我对命名约定有些困惑:

After several tests, I succeeded in finding a solution and make the SDK respect the timeout. During my tests, initially, I was a little confused about the naming convention:

timeoutIntervalForResource是传输可以花费的最长时间,无论成功与否.这对于AWS开发工具包来说是开箱即用的.

timeoutIntervalForResource is the maximum time that the transfer can take, regardless of any success / failure. This works out of the box with the AWS SDK.

timeoutIntervalForRequest是我们感兴趣的值.它是任务在网络丢失后等待其他数据的时间间隔.自最后一个接收到的数据包以来,就调度其计时器.正如您在问题和评论中所看到的那样,AWS开发工具包似乎并不尊重它.

timeoutIntervalForRequest is the value we are interested in. It is the time interval that the task waits for additional data after a network loss. Its timer is scheduled since the last packet received. As you can read in the question and comments, it does not appear to be respected by the AWS SDK.

此命名约定与Apple Cocoa USURLSession系列类相同.在研究期间,我遇到了这个 answer .对于将其配置实例化为后台配置的URLSession,似乎一直经历这种行为.这不是一个不当行为,它只是自iOS 8以来后台下载的新标准.

This naming convention is the same as Apple Cocoa USURLSession family of classes. During my research, I came across this answer. It appears that this behaviour has been consistently experienced for URLSessions that have their configuration instantiated as a background configuration. It is not a misbehaviour, it is just the new standard for background downloads since iOS 8.

现在,解决方案.通过在AWS开发工具包Objective-C代码中进行调试(是的,他们提供了完整的代码),我找到了位置.如果打开AWSS3TransferUtility.m文件,则在第400行左右找到此方法:

Now, the solution. By debugging around in the AWS SDK Objective-C code (Yes they provide the full code) I found the spot. If you open the AWSS3TransferUtility.m file, at line around 400, you will find, in this method:

- (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;

为了使其起作用,将第一条语句替换为:

In order to make it work, replace the first statement with:

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错误触发完成处理程序.

The SDK will fire the completion handler with a -1001 error after 30 seconds of network loss.

我仅在transferutilitydownload任务上进行了测试,但它也可以在上传中使用. 我知道此解决方案不是防弹解决方案,因为它没有考虑会话配置标识符,但是我会继续努力.此外,该解决方案还意味着更改AWS开发工具包代码,但仅更改一行代码.所做的更改只是使AWSS3TransferUtility创建标准的URLSessionConfigurations而不是后台的URLSessionConfigurations.这可能还有其他副作用需要考虑.

I only tested on a transferutilitydownloadtask, but it should work on upload too. I know this solution is not bullet proof as it does not take into account session configuration identifiers, but I will work on it. Also, the solution implies changing the AWS SDK code, but for a single line of code. The change simply makes the AWSS3TransferUtility create standard URLSessionConfigurations instead of background ones. This has probably other side effects to consider.

这篇关于在使用Amazon iOS SDK的快速iOS应用程序中,如何为AWSS3TransferUtility下载操作设置自定义超时?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆