我在后台模式下使用NSURLSession
,使用NSURLSessionUploadTask
从文件上传图像,以及委托回调。如果应用程序保留在后台而不是被用户杀死,那么所有这一切都可以正常工作。
但是,如果仍然有待上传的应用程序,并且使用主屏幕杀死应用程序,则重新启动应用程序并将未上载的图像作为具有相同背景标识符的新NSURLSession的上载任务重新排队,真的很奇怪:
1)任务只创建一次,并在发生任务时为其分配任务描述,NSURLSession
为每个会话分配一个唯一的任务标识符。我的NSURLSession
背景是单身。
2)由于此错误,任务几乎立即失败:
Error Domain=NSURLErrorDomain Code=-999 "The operation couldn’t be completed. (NSURLErrorDomain error -999.)" UserInfo=0x174669880 {NSErrorFailingURLStringKey=myURL, NSURLErrorBackgroundTaskCancelledReasonKey=0
并调用完成委托方法:
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
传递上述错误。此时,我打印出任务标识符和与我创建的任务相匹配的任务描述。
3)在所有这些任务几乎立即失败之后,那就是当事情开始变得怪异时,所有这些任务都会以某种方式再次放入NSURLSession
而没有我的代码做任何事情,请注意使用Charles我可以看到单一请求出去,实际上永远不会失败。这是他们第二次成功,这次他们再次调用didCompleteWithError
没有错误。此时打印任务描述和任务标识符,令人惊讶地返回我指定的相同任务描述,但是不同的任务标识符!这意味着iOS以某种方式重新创建具有相同任务标识符的任务并再次排队,即使它声称它失败了。请注意,网络请求只能在Charles中看到一次,而且从未真正失败
这是问题,因为我无法区分真正的上传错误和iOS生成的这个伪错误,因为我没有明确取消任何这些请求,我正在检查取消的错误代码,并选择忽略它因为我知道任务会被神奇地重新排列。这对我来说似乎是一个非常明显的错误,它可以一直复制。
随着解决方法的到位,一切都按预期工作,但这是一个黑客,我可以想象我可能在某个时候忽略真正的取消,并且从不通知客户端请求实际上失败了。
我在网上只找到了几个人来描述这个问题,但没有回复。
是否有雷达申请?有什么办法可以防止这种情况发生吗?
我正在使用8.1 SDK。