NSurlSession - 下载许多文件

Posted

技术标签:

【中文标题】NSurlSession - 下载许多文件【英文标题】:NSurlSession - downloading many files 【发布时间】:2013-11-22 12:22:14 【问题描述】:

我需要下载一些文件(大约 500 个)。我有一个包含这些文件的所有 url 的数组,我想使用 NSURLSession 以便我也可以支持后台下载。

我想不出正确的方法来实现这一点。如果我在一个完成后开始下一个文件下载,那么后台下载将无法工作。

我应该创建多个下载任务并启动吗?

请建议我如何实现这一目标。

【问题讨论】:

您可以为此使用队列。实现您自己的数据管理器,并相应地委托属性,并在功能上实现队列。另外我认为NSURLConnection 确实已经实现了这一点。所以,你可以忘记所有连接,直接要求NSURLConnection引导所有文件。 是否有令人信服的理由使用 NSURLConnection?或者你可以使用 NSURLSession (>= ios 7) 吗? 对不起,我在谈论 NSURLSession(现在编辑)。它支持后台下载,但它可以直接下载大文件,但我的问题是下载一些中小型文件。 【参考方案1】:

编辑: 首先,很抱歉回复晚了,这是您问题的解决方案。首先下载 Apple 的 Simple Background Transfer 示例。然后您将在视图控制器中看到 URLSessionDidFinishEventsForBackgroundURLSession 方法。您可以修改此方法以调用另一个下载任务,如下例所示,我认为这就是您想要做的。

还有一个类似这样的方法的注释会话代表将收到此消息,以表明之前为该会话排队的所有消息都已传递。因此,可以为您的请求创建一个队列比这个更好的解决方案。

- (void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session

    APLAppDelegate *appDelegate = (APLAppDelegate *)[[UIApplication sharedApplication] delegate];
    if (appDelegate.backgroundSessionCompletionHandler) 
        void (^completionHandler)() = appDelegate.backgroundSessionCompletionHandler;
        appDelegate.backgroundSessionCompletionHandler = nil;
        completionHandler();

        [self start:nil];
    

    NSLog(@"All tasks are finished");

【讨论】:

如果您有下载 500 个文件的要求,这不是自动暗示此操作必须是可取消和可恢复的吗? 如果我有这样的要求,是的,它必须是可取消的,但他没有提及任何相关内容。这可能是一个学校项目,或者他可能正在做一些基准测试。如果他会根据更具体的需求更新他的问题,我很乐意编辑我的答案。 请查看编辑,对于错误地提出问题,我深表歉意。恢复和取消将是要求的一部分,但目前我只是在寻找下载解决方案。 使用此解决方案,文件将按顺序下载,500个文件可能需要一段时间。【参考方案2】:

我遇到了这个问题。我的应用程序必须更新自身并使用背景获取在后台下载新闻视频以获取文件的 json 列表,然后触发 n 个网络服务调用以使用背景传输下载这些文件

[NSURLSessionConfiguration 背景会话配置:

我为每个文件创建了一个 NSSession 和一个 NSURLSessionDownloadTask。

file 1 - NSSession1 > NSURLSessionDownloadTask1
file 2 - NSSession2 > NSURLSessionDownloadTask2
file 3 - NSSession3 > NSURLSessionDownloadTask3

当应用程序在前台时,这会正常唤醒。

但是当应用程序处于后台并被 Background FETCH 唤醒时,我遇到了问题 一个文件会下载,然后它会停止。 就像只执行了第一个 NSSession1 一样。 可能是 iOS 一直在等待设备再次空闲才能运行下一个会话,但这太慢了

我通过一个 NSSession 并附加所有 NSURLSessionDownloadTask3 来让它工作

 NSURLSession * backgroundSession_ =
for(url to call)
   create NSURLSessionDownloadTask1 (set its session:backgroundSession_)
   create NSURLSessionDownloadTask2 (set its session:backgroundSession_)
   create NSURLSessionDownloadTask3 (set its session:backgroundSession_)

这样做时要小心 调用 NSSession finishTasksAndInvalidate 而不是 invalidateAndCancel

  //[session invalidateAndCancel];
   [session finishTasksAndInvalidate];

invalidateAndCancel 将停止会话并且不完成其他下载任务

【讨论】:

以上是关于NSurlSession - 下载许多文件的主要内容,如果未能解决你的问题,请参考以下文章

AFNetworking/NSURLSession耗时长创建100多个任务下载文件

可以使用不同的配置多次创建 NSURLSession 对象吗?

如何使用 iOS 7 的 NSURLSession 接受自签名 SSL 证书

iOS NSURLSession 实现网络请求-文件下载-上传-后台下载

iOS 使用NSURLSession下载大文件

NSURLSession下载文件-代理