【问题标题】:Amazon S3 iOS SDK background upload with progress block带有进度块的 Amazon S3 iOS SDK 后台上传
【发布时间】:2016-01-15 12:20:38
【问题描述】:

我正在开发一个依赖 AWS 进行文件上传和下载的应用程序。在上传的情况下,当我使用 AWSS3TransferManagerUploadRequest 上传视频文件时,我可以使用进度块显示进度条,但是当我按下主页按钮并且应用程序进入后台时,上传暂停(可能是因为它使用了 NSURLConnection)。只有当应用程序在前台运行时才会上传。

这是使用 AWSS3TransferManagerUploadRequest 上传文件的代码。

AWSS3TransferManager *transferManager = [AWSS3TransferManager defaultS3TransferManager];

AWSS3TransferManagerUploadRequest *uploadRequest = [AWSS3TransferManagerUploadRequest new];

uploadRequest.bucket = bucketName;
uploadRequest.key = appropriateKey;

uploadRequest.body = [NSURL fileURLWithPath:filePath];

uploadRequest.contentType = contentType;

uploadRequest.uploadProgress = progressBlock;


[[transferManager upload:uploadRequest] continueWithExecutor:[AWSExecutor mainThreadExecutor] withBlock:^id(AWSTask *task) {
    if (task.error)
    {
        if ([task.error.domain isEqualToString:AWSS3TransferManagerErrorDomain])
        {
            switch (task.error.code)
            {
                case AWSS3TransferManagerErrorCancelled:
                case AWSS3TransferManagerErrorPaused:
                    break;

                default:
                    failBlock(task.error.code, task.error.localizedDescription);
                    break;
            }
        }
        else
        {
            failBlock(task.error.code, task.error.localizedDescription);
        }
    }
    if (task.result)
    {
        AWSS3TransferManagerUploadOutput *uploadOutput = task.result;
        successBlock(uploadOutput);
    }
    return nil;
}];

这工作,除了在后台传输。

所以,我继续使用 AWS 的预签名 URL。以下是相同的代码。

AWSS3GetPreSignedURLRequest *getPreSignedURLRequest = [AWSS3GetPreSignedURLRequest new];
getPreSignedURLRequest.bucket = bucketName;

getPreSignedURLRequest.key = appropriateKey;
getPreSignedURLRequest.HTTPMethod = AWSHTTPMethodPUT;
getPreSignedURLRequest.expires = [NSDate dateWithTimeIntervalSinceNow:3600];


//Important: set contentType for a PUT request.
NSString *fileContentTypeStr = contentType;
getPreSignedURLRequest.contentType = fileContentTypeStr;
[[[AWSS3PreSignedURLBuilder defaultS3PreSignedURLBuilder] getPreSignedURL:getPreSignedURLRequest]
 continueWithBlock:^id(AWSTask *task) {

     if (task.error) {
         NSLog(@"Error: %@",task.error);
     } else {

         NSURL *presignedURL = task.result;
         NSLog(@"upload presignedURL is: \n%@", presignedURL);

         NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:presignedURL];
         request.cachePolicy = NSURLRequestReloadIgnoringLocalCacheData;
         [request setHTTPMethod:@"PUT"];
         [request setValue:fileContentTypeStr forHTTPHeaderField:@"Content-Type"];


         NSURLSession *session;
         NSURL *uploadFileUrl = [NSURL fileURLWithPath:filePath];
         NSURLSessionUploadTask *uploadTask = [session uploadTaskWithRequest:request fromFile:uploadFileUrl];
         //uploadTask is an instance of NSURLSessionDownloadTask.
         //session is an instance of NSURLSession.
         [uploadTask resume];

     }

     return nil;
 }];

这样就解决了后台上传的问题。但它没有进度块,因此我无法跟踪进度。

我必须能够跟踪进度并从后台上传。这可能吗?或者有什么解决方法吗?

【问题讨论】:

  • 您是否找到了同时进行预签名、上传和跟踪进度的方法?
  • @Eusthace 检查我的答案.. 我做到了。他们提供 TransferUtility。它仍处于测试阶段,但可以按要求工作。

标签: ios objective-c amazon-web-services amazon-s3


【解决方案1】:

所以,我做了很多挖掘工作并找到了答案。它可能对某人有帮助。

AWSS3TransferManager 有进度块来跟踪进度,但不支持后台传输。 AWSS3GetPreSignedURLRequest 支持后台传输,但无法跟踪进度。

他们还有另一项服务,您可以通过该服务在后台跟踪进度并上传/下载。使用 AWSS3TransferUtility,您可以做这两件事。请注意,这仍处于测试阶段。

请参阅文档以获取更多信息 - http://docs.aws.amazon.com/mobile/sdkforios/developerguide/s3transferutility.html

我在这方面遇到了很多麻烦(部分是由于我的无知)。我希望这对任何有类似问题的人有用。

【讨论】:

  • 是的,也有同样的问题。花了很多时间实现 TransferManager 才发现它对我的情况毫无用处。更烦人的是,虽然 TransferManager 可以很容易地与 tableview 和多个上传集成。 TransferUtility 没有。在我看来,AWS SDK 一直很不直观。
  • 我正在使用 AWSS3TransferUtility 上传文件。上传正在后台进行,但由于网络中断,上传进度为零。就我而言,它应该具有网络可访问性。这可能吗?
  • @Ada 我认为传输实用程序不支持并行上传,如果您不支持并行上传,为什么不制作 AWSS3TransferUtilityUploadTask 的单个对象并在其上调用 resume。如果这不起作用,那么它可能无法在网络丢失时恢复它。参考docs.aws.amazon.com/mobile/sdkforios/developerguide/…
  • @MeharoofNajeeb 我支持并行上传。网络恢复后,我也尝试过在单个 AWSS3TransferUtilityUploadTask 上恢复,但它不起作用。上传正在重新启动。您能否向我确认这是不可能的,或者有办法做到这一点。
  • @Ada 目前尚无法使用 AWSS3TransferUtility 支持网络丢弃恢复。我刚刚再次浏览了他们的文档。如果您想支持这一点,为什么不尝试分段上传功能呢?
【解决方案2】:

抱歉,使用核心 iOS 后台上传功能根本不支持这一点。

按照设计,NSURLSession 后台上传将占用 100 个并行块,并且通常只返回成功/失败作为原子响应。实际进度对应用程序是不透明的。

您无法真正解决这个问题,您序列化的次数越多,触发“下一部分”上传的次数就越多,这很快就会引起速率限制方面的愤怒。

后台上传经过专门设计,可减少触摸以节省电池和 3G 数据使用量。它不是为任何交互而设计的。

我想知道,鉴于需要使用后台上传,大概是大型资产,实际需要向用户显示可能非常缓慢的进度是什么?成功/失败还不够吗?

也许要解决这个问题,如果绝对必要,您可以在前台运行上传,然后您会收到反馈,如果用户厌倦了等待或手机休眠,则在应用程序拆解回调中,切换到恢复因为用户不再有兴趣观看进度条,所以在后台任务上执行?

【讨论】:

    猜你喜欢
    • 2012-02-14
    • 1970-01-01
    • 2014-10-05
    • 2017-04-28
    • 2013-07-21
    • 1970-01-01
    • 1970-01-01
    • 2013-01-28
    • 1970-01-01
    相关资源
    最近更新 更多