带有 URL 的 NSURLSession downloadTask 返回 nil

Posted

技术标签:

【中文标题】带有 URL 的 NSURLSession downloadTask 返回 nil【英文标题】:NSURLSession downloadTaskWithURL returns nill 【发布时间】:2014-03-28 10:54:53 【问题描述】:

我的应用程序中的NSURLSessionDownloadTask 有问题我使用代码创建了数百个下载任务:

NSURLSessionDownloadTask * task = [_urlSession downloadTaskWithURL:downloadUrl];
NSLog(@"session: %@, download task %@ for url: '%@'",_urlSession, task, downloadUrl);
if (!task)

     NSLog(@"ooops no task");
else


 

在 xcode 控制台中,我有这样的消息:

2014-03-28 11:23:39.297 MYAPP[3838:60b] session: <__NSCFURLSession: 0x19471e70>, download task (null) for url: 'http://xxx.cloudfront.net/seminarcontent/nsm_photos_11_24d8505e-4ddd-4e9b-baef-a90d5e322702.jpg'

我也在管理器的控制台中看到这条消息:

nsnetworkd[322] <Error>: __NSCFLocalDownloadFile: error 2 creating temp file: /private/var/mobile/Applications/MYAPPGUID-BD21-4C5A-8DB6-845D80BE75E3/Library/Caches/com.apple.nsnetworkd/CFNetworkDownload_R91Hqn.tmp

NSURLSession 之前创建的:

_urlSession = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration  backgroundSessionConfiguration:sessionIdenttificator] delegate:self delegateQueue:nil];

所有网址都是有效的,只有当我在应用启动后开始下载时才会发生这种情况

请分享您对我的问题的想法。提前致谢。

更新:

我还添加了对缓存目录的检查,确保在我开始下载之前存在但没有任何改变

编辑

附加信息,我无法在模拟器中或在调试模式下的设备上重现该错误(启用断点)。

【问题讨论】:

nsnetworkd 是代表您进行后台下载的守护进程。它将下载的 URL 存储在临时/私有位置。它失败了,因为它无法创建存储下载文件的临时文件。错误 2 是 ENOENT,在这种情况下,这意味着该目录不存在。是否有可能您更改了您的应用程序ID?你在模拟器中。您为什么不实际启动一个终端并转到该目录。此外,记录您的应用实际使用的缓存目录。也许守护进程和您的应用对应用 ID 感到困惑。 @JodyHagins 感谢您关注我的麻烦。我和你一样理解这个错误,但不知道为什么会这样,我没有更改 bundleId,也无法在模拟器中重现。 因此,如果设备上发生这种情况,则可能是一些错误或竞争条件。我从来没有见过它发生。我建议您创建会话,然后致电getTasksWithCompletionHandler:。在完成处理程序中,忽略返回的任务......它很可能是空的,即使守护程序有任务......然后开始您的下载请求。该调用至少应该与守护程序(或某些共享数据结构)进行某种通信。无论如何,回调将在会话的委托队列中,并且可以在启动时避免这种竞争条件。 另外,你知道它会创建Library/Caches/com.apple.nsnetworkd/,所以也许你可以先创建那个目录,虽然它可能是用特殊凭据创建的,你的创建可能引起问题...我承认我没有遇到过这个问题,并且在创建目录结构后我还没有检查过目录结构...但是值得尝试一下。 FWIW,后台任务机制我用的比较多,也发现了很多问题,所以如果有问题我也不奇怪……不过总体来说,这个功能很棒。 【参考方案1】:

终于,经过几天的调试,找到了部分解决方案。

  @synchronized(_urlSession)
  
      task = [_urlSession downloadTaskWithURL:downloadUrl];
  

我在我的代码中添加了锁,现在一切正常,但我想这不是一个解决方案,只是一种避免问题的方法。

感谢@Jody Hagins 提供了非常有帮助的 cmets。

【讨论】:

以上是关于带有 URL 的 NSURLSession downloadTask 返回 nil的主要内容,如果未能解决你的问题,请参考以下文章

带有令牌认证的 NSURLSession

带有 NSURLSession 的 Swift 中的 HTTP 请求

带有 NSURLSession 的 Http/2 server_push

使用带有参数的 NSURLSession (HTTP POST) 下载 PDF

使用 NSURLSession downloadTaskWithResumeData: 时如何更改 URL?

管理错误时,带有 JSON 数据参数的 NSURLSession 崩溃为零