我应该如何在backgroundConfiguration中使用NSURLSession将多个文件的块上传到Amazon S3(iOS7)

Bar*_*oon 2 iphone amazon-s3 ios afnetworking-2 nsurlsession

目前我正在开展一个项目,我们需要将一组照片和视频发送到S3亚马逊服务器.流程是这样的:

- 首先我们要求api开始转移,我们得到一个id(api call)

-transfer id - >请求文件上传到api - > file_id作为响应(api调用)

-file id - >在api请求块上传 - > amazon数据作为响应(api调用)

-upload chunck - >在backgroundConfiguration中配置的NSURLSession中(每次上传5mb)

上次chunck-upload(api调用)后上传文件

上次文件上传后的最终转移(api通话)


我们需要使用api并对其进行调用..当应用程序在后台运行时也是如此.

所以我想的是使用可以在后台上传文件然后运行完成块的AFNetworking 2.0.


在完成块中,代码如下:

 _managerBackground = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];


    - (void)uploadChunkInTheBackGround:(RequestChunkUploadResponse *)requestChunkUploadResponse
    {
        UploadChunkRequest *chunkUploadRequest = [[UploadChunkRequest alloc]initWithRequestChunkUploadResponse:requestChunkUploadResponse];

        APIService *weakSelf = (APIService *)self;

         NSURLSessionUploadTask *uploadTask = [_managerBackground uploadTaskWithRequest:chunkUploadRequest.request fromFile:chunkUploadRequest.fileLocationURL progress:nil completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) {
       //code to prepare recursive upload and files
        [weakSelf uploadChunkInTheBackGround:chunkUploadResponse];
    }];
Run Code Online (Sandbox Code Playgroud)

所以困难在于我们喜欢执行代码并尝试在iOS7的后台执行上传任务

当应用程序连接到调试器(Xcode)时,上面的示例工作.但没有它在控制台中提供此错误:

<BKProcessAssertion: 0x178468380> identifier: com.apple.nsnetworkd.handlesession process: YourApp[675] permittedBackgroundDuration: 30.000000 reason: backgroundDownload owner pid:111 preventSuspend  preventThrottleDownUI  preventIdleSleep  preventSuspendOnSleep
Run Code Online (Sandbox Code Playgroud)

所以这不酷:(

有没有办法运行代码,并在后台上传文件.. ?? 你有这方面的经验吗?或者我们要求iOS7的大部分?

我希望你能分享你的想法.

谢谢,

亲切的问候,

Bart Schoon

los*_*und 8

您在控制台上看到的错误是iOS针对后台任务强制执行的30秒限制.一旦NSURLSessionTask在后台完成.您的应用在后台启动,您的应用会在appDelegate中接听电话.此时,您应该存储完成处理程序,排队下一个上载任务并调用完成处理程序,以便可以获取新快照并使您的应用程序重新进入休眠状态.

- (void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)())completionHandler {

   // store completion handler

}
Run Code Online (Sandbox Code Playgroud)

现在我不确定何时强制执行30秒限制.在早期版本的iOS 7版本中,仅当您的应用程序在内存不足后重新启动时才会强制执行,但在最新版本(7.0.3)中,即使在挂起模式下它也有时会强制执行.通常,没有太多内容Apple文档中的信息,因此我们需要根据反复试验来弄清楚.

我认为你的问题是你让上传在后台继续而没有调用完成处理程序,这就是为什么你的应用程序崩溃了.我不认为NSURLSession意味着在后台连续上传大量文件.

假设我们正在执行后台并且所有api调用都是在后台进行的,那么这就是您的上传工作方式.

1)创建并恢复任务以调用api获取ID - 调用完成处理程序.

2)任务在后台完成,您的应用程序启动.让我们假设你有30秒.您应该首先解析您将获得ID的响应.然后设置下一个任务来请求文件上传,调用完成处理程序.

3)任务在后台完成,您的应用程序再次启动.现在,您将解析响应,为您提供文件ID,然后设置下一个用于分块上传的任务,调用完成处理程序.

所以基本上总结一下,在后台,你应该在你设置的每个任务之后调用完成处理程序.如果你不这样做,最终你的应用程序将崩溃.

调用完成处理程序会严重降低您的上传速度,因为您依靠iOS重新启动您的应用程序,只要感觉它,但此时我还没有看到更好的解决方案