6

原来我以为如果一个NSURLSessionDownloadTask成功完成URLSession:downloadTask:didFinishDownloadingToURL:方法将被调用,如果由于某种原因失败 - URLSession:task:didCompleteWithError:。 它在仿真器上按预期工作(只有一种此方法被称为一个下载任务),但在设备上情况并非如此:如果失败,这两种方法都被调用,URLSession:downloadTask:didFinishDownloadingToURL:是第一个。 (这两种方法在参数中通过相同的任务)处理NSURLSessionDownloadTask失败

有什么我失踪了吗?

+0

我注意到didFinishDownloadingToURL与didCompleteWithError并行调用的行为相同。这给我们造成了巨大的问题。你是如何解决这个问题的?在这种情况下, – RunLoop

+0

的位置可能是无效的。你能检查一下吗? – AsifHabib

回答

1

完工块,而不是代表:

NSURLSessionDownloadTask *mySessionDownloadTask = [myURLSession downloadTaskWithRequest:myRequest completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) 
{ 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     if(!error) 
     { 
      // Finish loading 
     } 
     else 
     { 
       // Handle error 
     }); 
}]; 

注意:如果你没有得到主队列,与用户界面中的任何更新将被延迟导致没有料到的行为。

+1

我希望我的用户在我的应用进入后台模式时完成下载,因此我无法使用完成块而不是代理(因为我使用后台会话) – dariaa

+0

我得到您。那么如何使用全局BOOL来知道您是否已经处理了响应? –

+0

那么,当然可以有一个解决方法,但我想要更深入的了解。这是预期的行为还是应该报告的错误等等顺便提一句,'BOOL'标志并不是最好的选择,因为在'URLSession:downloadTask:didFinishDownloadingToURL:'(首先被调用)中,通常会将文件复制到文档目录中以供进一步处理。在这一点上知道下载是否成功完成或有错误是很好的。 – dariaa

-1

NSURLSessionDownloadTaskNSURLSessionTask的一个子类,它具有error属性。在尝试复制文件之前,您可以在URLSession:downloadTask:didFinishDownloadingToURL:委托方法中检查吗?

+0

错误属性保持为零,除非它是客户端错误。 –

1

根据苹果公司的文档NSURLSessionDownloadDelegate这是标准的行为。

/* Sent when a download task that has completed a download. The delegate should 
* copy or move the file at the given location to a new location as it will be 
* removed when the delegate message returns. URLSession:task:didCompleteWithError: 
* will still be called. */ 
0

我发现了一个解决这个问题:

要获得在响应头的状态代码,您必须首先启动NSURLSessionDataTask

这将调用以下代理方法URLSession:dataTask:didReceiveResponse:completionHandler:

在这种方法中,你可以先检查NSURLResponse参数的状态代码(通过将其强制转换为NSHTTPURLResponse),最后调用完成处理程序与任何NSURLSessionResponseBecomeDownload您dataTask转换为downloadTask(这将表现为您可能期望从NSURLSessionDownloadTask获取)或NSURLSessionResponseCancel以避免下载一些您不需要的数据(例如,如果响应的状态码为404)。

另外,如果你需要做的转换NSURLSessionDownloadTask东西(如存放在数组或字典或与新对象替换数据的任务),它可以在URLSession来完成:dataTask:didBecomeDownloadTask:

希望这可以帮助别人!