是否应该使用自定义委托为NSURLSessionUploadTasks调用didReceiveResponse?

Jas*_*run 4 delegates ios7 nsurlsession

我正在调查使用NSURLSessionUploadTasks来管理几个文件的后台上传.会话使用以下内容创建:

_urlsession = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration backgroundSessionConfiguration:identifier] delegate:self delegateQueue:nil];
Run Code Online (Sandbox Code Playgroud)

这是在符合的类中创建的URLSessionDataTaskDelegate,并且具体定义:

– URLSession:dataTask:didReceiveResponse:completionHandler:
– URLSession:dataTask:didBecomeDownloadTask:
– URLSession:dataTask:didReceiveData:
Run Code Online (Sandbox Code Playgroud)

每次调用其中一个委托时,都会记录到控制台.

然后,使用以下代码创建上载任务:

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';
Run Code Online (Sandbox Code Playgroud)

但是,我得到的委托回调序列并不像预期的那样:

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:
Run Code Online (Sandbox Code Playgroud)

值得注意的是,身体数据按预期发送,但随后立即切换到didReceiveData委托回调,didReceiveResponse事先没有回调.这对我来说是一个意想不到的行为:我希望收到有关响应的信息,以便我可以正确设置数据,或者更好的是,将任务转换为下载任务以将响应保存到文件中.

如果在默认URL会话中提交上载任务,则调用didReceiveResponse,我可以成功将任务转换为后台下载任务.

我在Apple的文档中找不到是否didReceiveResponse应该NSURLSessionUploadTask在后台调用s的任何迹象.它们似乎应该:文档NSURLSessionUploadTask表明它是NSURLSessionDataTask行为中有少量修改的子类,但列出的差异都不涉及不发送didReceiveResponse回调.没有任何特定于后台会话的文档提到此限制.

这是一个错误,还是错过/误解了一些文档,说明后台的上传任务没有调用didReceiveResponse

sna*_*had 6

在最近的Tech Talks期间,我向Apple工程师询问了这一点.他们跟进并给出了以下响应 - 并不完全令人满意,我觉得他们应该记录这种行为,如果它与任何其他HTTP处理流程不同.特别是因为前景行为确实获得了didReceiveData,但没有获得didReceiveResponse.他们至少需要记录这种非显而易见的行为.

"今天的工作方式是我们不会发送didReceiveResponse回调用于后台上传,以避免在应用程序尚未运行时唤醒应用程序.缺点是应用程序无法选择将后台上传转换为下载任务我们的决定是基于期望文件上传的响应数据很小,因此将响应数据传递给客户端,因为NSData而不是下载的文件就可以了."

  • 如果收到非200响应且身体是空的,会发生什么?我们如何期望接收和处理此响应?如果有数据,我们可以假设didReceiveData只被调用一次吗?这与平台上每个其他基于委托的HTTP处理程序的生命周期非常相似.应清楚地记录和解释所有差异. (3认同)