2013-10-03 22 views
4

我在調查使用NSURLSessionUploadTasks來管理幾個文件的後臺上傳。該會話使用創建:應該使用自定義委託來爲NSURLSessionUploadTasks始終調用didReceiveResponse嗎?

_urlsession = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration backgroundSessionConfiguration:identifier] delegate:self delegateQueue:nil]; 

這是符合URLSessionDataTaskDelegate類中創建,並明確規定:

– URLSession:dataTask:didReceiveResponse:completionHandler: 
– URLSession:dataTask:didBecomeDownloadTask: 
– URLSession:dataTask:didReceiveData: 

而且每次登錄到控制檯這些代表之一被調用。

然後,上傳任務用下面的代碼創建:

NSString *urlString = [NSString stringWithFormat:@"%@%@?filename=%@", HOST, UPLOAD_PATH, filename]; 
NSMutableURLRequest *attachmentUploadRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlString]]; 
attachmentUploadRequest.HTTPMethod = @"POST"; 
[attachmentUploadRequest addValue:@"application/binary" forHTTPHeaderField:@"Content-Type"]; 

NSURLSessionTask* task = [_urlsession uploadTaskWithRequest:attachmentUploadRequest fromFile:filePath]; 
task.taskDescription = 'upload'; 

但是,並不如預期的委託回調,我得到的序列:

URLSession:didReceiveChallenge:completionHandler:]:196: Respond with <NSURLCredential: 0x1cf4fe00>: 
URLSession:task:didSendBodyData:totalBytesSent:totalBytesExpectedToSend:]:282: Task 'upload' sent 32768 bytes 
URLSession:task:didSendBodyData:totalBytesSent:totalBytesExpectedToSend:]:282: Task 'upload' sent 48150 bytes 
URLSession:dataTask:didReceiveData:]:222: Task 'upload' got some data: 

值得注意的是,身體數據如預期的那樣發送,但然後它立即切換到didReceiveData代表回調,並且事先沒有didReceiveResponse回調。這對我來說是一種意想不到的行爲:我期望收到有關響應的信息,以便我可以正確設置數據,或者更好的是,將任務轉換爲下載任務以將響應保存到文件。

如果上傳任務在默認的URL會話中提交,那麼didReceiveResponse被調用,並且我可以成功地將任務轉換爲後臺下載任務。

我在Apple的文檔中找不到didReceiveResponse應該在後臺調用NSURLSessionUploadTask s的任何跡象。它似乎,他們應該:NSURLSessionUploadTask的文檔表明它是NSURLSessionDataTask的子類,行爲有小的修改,但所列出的任何差異都不涉及發送didReceiveResponse回調。沒有一個背景會話特定的文檔提到了這個限制。

這是一個錯誤,或者錯過了/解釋了一些文檔說明上載任務在後臺不叫didReceiveResponse

回答

6

在最近的技術會議期間,我問蘋果的工程師。他們跟進並給出了以下回應 - 不完全令人滿意,我覺得他們應該記錄這種行爲,如果它不同於任何其他HTTP處理流程。特別是因爲前景行爲確實得到了didReceiveData,但沒有得到didReceiveResponse。至少他們需要記錄這種不明顯的行爲。

「今天工作的方式是,我們不會發送didReceiveResponse回調函數用於背景上傳,以避免在應用程序尚未運行時喚醒它。缺點是應用程序無法選擇將背景上傳轉換爲下載我們的決定是基於期望上傳文件的響應數據很小,因此將響應數據作爲NSData傳遞給客戶端,而不是下載文件就沒有問題。「

+3

如果收到非200響應並且主體爲空,會發生什麼情況?我們希望如何接收和處理這種迴應?如果有數據,我們可以假設didReceiveData只被調用一次嗎?這是平臺上每個其他基於代理的HTTP處理程序的生命週期的一個重要背離。所有的差異應該清楚地記錄和解釋。 –

+0

更新 - 我得到了Apple的回覆,我應該在iOS 8中再次測試它。所以我試了一下,但沒有奏效。所以我去了開發者,因爲我在WWDC,並告訴他們修復程序沒有工作。事實證明,修正是在標題中的一條評論,說它不起作用(這是一種改進)。我有一些關於他們爲什麼這樣做的背景,但我仍然認爲他們可以禮貌地致電didReceiveResponse並使其更加一致。我仍在爲此而競選。 – snarshad

+1

@JasonLeBrun如果我正確理解你的問題,在這種情況下,你會得到一個URLSession:任務:didCompleteWithError:你的委託上的回調,在task.response中有迴應。 (這在NSURLSessionTaskDelegate協議中,是你實現的協議的父協議。) –

相關問題