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:

希望這可以幫助別人!