在 iOS8 中使用 NSUrlSession 使用流请求进行后台上传
Posted
技术标签:
【中文标题】在 iOS8 中使用 NSUrlSession 使用流请求进行后台上传【英文标题】:Background Upload With Stream Request Using NSUrlSession in iOS8 【发布时间】:2015-02-04 06:49:23 【问题描述】:之前在 ios7 中,当我们尝试在后台使用流请求上传时,会出现以下异常
由于未捕获的异常“NSGenericException”而终止应用,原因:“后台会话中的上传任务必须来自文件”
但在 iOS8 中,当我们尝试在后台使用流上传时也不例外。
现在我的问题是
1) iOS8 中是否允许使用 uploadTaskWithStreamedRequest: 进行 backgourd 上传?
2) 在 iOS8 中,我使用带有 uploadTaskWithStreamedRequest 的后台 NSURLConfiguration。我正在使用 -(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task needNewBodyStream:(void (^)(NSInputStream *))completionHandler 向 NSUrlSession 提供流。当应用程序处于前台时,它工作正常并将我的文件上传到服务器。但是一旦应用程序在后台运行,流就会结束并且 NSURLSession 完成并出现以下错误
Error Domain=NSURLErrorDomain Code=-997 "失去与后台传输服务的连接"
我认为当应用程序进入后台时,我的流会结束。现在我的问题是我应该在哪个 runloop 中安排我的 Stream 或者让我知道我的理解是否有任何错误。
-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task needNewBodyStream:(void (^)(NSInputStream *))completionHandler
// Open producer/consumer streams. We open the producerStream straight
// away. We leave the consumerStream alone; NSURLConnection will deal
// with it.
NSLog(@"%@", [NSThread currentThread]);
NSInputStream *consStream;
NSOutputStream *prodStream;
[NSStream createBoundInputStream:&consStream outputStream:&prodStream bufferSize:SFAMaxBufferLength];
assert(consStream != nil);
assert(prodStream != nil);
self.consumerStream = consStream;
self.producerStream = prodStream;
self.producerStream.delegate = self;
[self.producerStream scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
[self.producerStream open];
// Set up our state to send the body prefix first.
self.buffer = [self.bodyPrefixData bytes];
self.bufferLimit = [self.bodyPrefixData length];
completionHandler(self.consumerStream);
【问题讨论】:
【参考方案1】:您无法使用后台配置上传流式任务。我只在两种情况下成功上传数据:
-
使用存储在请求正文中的数据下载任务。
从文件上传任务。在这种情况下,您将不会收到响应正文。
【讨论】:
如果您可以共享任何文档链接以指出 backgroundTask 仅支持从文件上传而不支持从正文或 NSStream 上传,那就太好了? 不幸的是,他们没有记录很多关于后台传输的内容。我之所以知道这些,是因为我们做了很多研究。【参考方案2】:您可以在后台上传多部分文件 - 只是这不是直截了当的。参考:AFNetworking error in uploadTaskWithStreamedRequest
【讨论】:
请注意 link-only answers 是不鼓励的,所以答案应该是寻找解决方案的终点(而不是另一个参考中途停留,随着时间的推移往往会变得陈旧)。请考虑在此处添加独立的概要,保留链接作为参考以上是关于在 iOS8 中使用 NSUrlSession 使用流请求进行后台上传的主要内容,如果未能解决你的问题,请参考以下文章
iOS8:NSURLSession:NSURLSessionDataTask '客户端在收到整个响应之前关闭连接'