带有进度块的亚马逊 S3 iOS 开发工具包后台上传



我正在开发一个依赖 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;
 }];

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

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

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

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

他们有另一项服务,您可以通过该服务在后台跟踪进度和上传/下载。使用 AWSS3TransferUtility,您可以同时执行这两项操作。请注意,这仍处于测试阶段。

有关详细信息,请参阅文档 - http://docs.aws.amazon.com/mobile/sdkforios/developerguide/s3transferutility.html

我对此有很多麻烦(部分原因是我的无知)。我希望这对有类似问题的人有用。

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

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

真的无法解决这个问题,你序列化的越多,你触发的"下一部分"上传就越多,这将很快招致速率限制方面的愤怒。

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

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

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

相关内容

最新更新