Ios NSURLSessionPloadTask获取响应数据
在使用Ios NSURLSessionPloadTask获取响应数据,ios,nsurlsession,nsurlsessionuploadtask,Ios,Nsurlsession,Nsurlsessionuploadtask,在使用NSURLSessionframework时,我有一些误解,这就是为什么我决定从头开始编写小型应用程序,而不使用AFFramework/Alamofire 我有一个API,需要执行以下步骤才能上载文件: 后置文件数据 获取响应(JSON) 将一些json字段发布到api/save 我有这样一个配置的后台会话: let configuration = NSURLSessionConfiguration.backgroundSessionConfigurationWithIdentifier(
NSURLSession
framework时,我有一些误解,这就是为什么我决定从头开始编写小型应用程序,而不使用AFFramework/Alamofire
我有一个API,需要执行以下步骤才能上载文件:
api/save
let configuration = NSURLSessionConfiguration.backgroundSessionConfigurationWithIdentifier("myBackground")
let session = NSURLSession(configuration: configuration, delegate: self, delegateQueue: nil)
我实现了两种方法:
func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveData data: NSData)
在这里我聚集了所有的数据
及
在这里,我将此数据转换为响应对象。这个响应对象对我来说非常重要
一切正常,虽然应用程序在前台,但我在后台有问题
案例1
我刚开始上传数据,应用程序就崩溃了。根据WWDC,我需要实施
func application(application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: () -> Void)
并在didpletewherror
方法中调用此处理程序。但在调用此方法之前,我需要使用上传响应中的数据调用api/save
。
如何获取这些数据
案例2
大多数情况类似。用户在上载过程中停止应用程序。然后在会话处理我的任务时,在几秒钟内加载应用程序。现在会话调用didReceiveData,但是当然,有些数据丢失了。在这种情况下我该怎么办?如何恢复响应数据?您没有提到实现
urlsessiondifinisheventsforbackgroundurlsession
(一种nsurlsessionelegate
方法)。你真的也想实现这一点。基本过程是:
- 在应用程序代表的
中,您应该:handleEventsForBackgroundURLSession
- 启动后台
(它将开始接收与所有上载相关联的委托方法调用);及NSURLSession
- 保存完成处理程序(但不要调用它)李>
- 启动后台
- 然后,在
中(处理完所有响应后),调用保存在urlsessiondifinisheventsforbackgroundurlsession
中的完成处理程序。(确保将其分派到主队列。)handleEventsForBackgroundURLSession
didReceiveData
调用将附带对各种上载的响应
我只是做了一个快速测试,上传了5个20mb的图像,然后立即终止了应用程序。然后,即使应用程序没有运行,我看到五个文件慢慢地出现在我的服务器上(显然是由守护进程处理的)。当所有五个都完成后,by app在后台透明地重新启动,调用了handleEventsForBackgroundURLSession
(它重新启动了会话),它让所有的didReceiveData
调用快速被调用,完成后,调用了urlsessiondFinisheventsforBackgroundurlsession
,然后我的应用程序才调用了保存的完成处理程序
至于这对你不起作用的原因,还不足以诊断问题。可能性包括:
- 也许你不恰当地终止了应用程序。你不能通过双击home按钮并在那里终止应用程序来终止应用程序;您必须让它自己自然终止,或者出于诊断/测试目的,我通过在代码中调用
强制它终止exit(0)
- 可能在调用
时您没有重新启动会话handleEventsForBackgroundURLSession
- 可能您调用提供的完成处理程序太早(即调用
之前)urlsessiondifinisheventsforbackgroundurlsession
这很难说,但我怀疑在您的实现中隐藏着一些不太正确的东西,并且根据提供的信息很难说它是什么(假设它不是上述要点之一)。不幸的是,调试此后台会话非常复杂,因为当应用程序终止时,它不再连接到调试器,因此您无法轻松调试应用程序通过iOS自动重新启动后发生的事情)。就我个人而言,我要么记录消息,只看设备控制台(以及服务器上显示的内容),要么在应用程序本身中构建一些持久的日志机制。对于测试后台会话代码,建议在真实设备上测试。在编写使用NSURLSession后台会话支持的应用程序时,很容易被开发过程中三个不明显的工件弄糊涂:
- 当您从Xcode运行应用程序时,Xcode会将应用程序安装到一个新容器中,这意味着应用程序的路径会发生变化。这可能会混淆NSURLSession的后台会话支持。 注意:此问题已在iOS 9中修复;如果您在iOS 9或更高版本中遇到NSURLSession未处理容器路径更改的问题,请提交错误
- Xcode的调试阻止系统挂起你的应用程序。因此,如果您从Xcode运行应用程序,或者在启动后的某个时间连接到该进程,然后将应用程序移动到后台,则应用程序将在系统可能会暂停它的情况下继续执行
- 同样,iOS模拟器也无法准确模拟应用程序暂停和恢复;这在过去是有效的,但在iOS 8或iOS 9模拟器中不起作用
来源:谢谢你的精彩解释。我把你的答案标为“正确”,因为(我相信)它能解决别人的问题。然而,我实现了
urlsessiondifinisheventsforbackgroundurlsession
,但运气不好。我重新启动了bg会话,得到了URLSession(会话:NSURLSession,数据任务:NSURLSessionDataTask,didReceiveData:NSData)
我得到了以下数据:session:dataTask:{taskIdentifier:1}数据:0
,当我试图追加数据时,它会使我的应用程序崩溃
func application(application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: () -> Void)