首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NSURLSessionUploadTask获取响应数据

NSURLSessionUploadTask获取响应数据
EN

Stack Overflow用户
提问于 2016-01-13 07:00:32
回答 2查看 942关注 0票数 2

我在使用NSURLSession框架时有一些误解,这就是为什么我决定从头开始编写小应用程序,而不使用AFFramework/Alamofire。

我有一个API,它需要以下步骤来上传文件:

  1. POST文件数据
  2. 获取响应(JSON)
  3. 将一些json字段发布到api/save

我有一个具有这样的配置的后台会话:

代码语言:javascript
复制
let configuration = NSURLSessionConfiguration.backgroundSessionConfigurationWithIdentifier("myBackground")
let session = NSURLSession(configuration: configuration, delegate: self, delegateQueue: nil)

我实现了两个方法:

代码语言:javascript
复制
func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveData data: NSData)

在这里我聚合了所有数据

代码语言:javascript
复制
func URLSession(session: NSURLSession, task: NSURLSessionTask, didCompleteWithError error: NSError?)

将这些数据转换为响应对象。这个响应对象如果对我非常重要的话。

当应用程序在前台时,一切都很好,但是我在后台有问题。

案例1

在我开始上传数据之后,App就崩溃了。根据WWDC,我需要实现

代码语言:javascript
复制
func application(application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: () -> Void)

并在didCompleteWithError方法中调用此处理程序。但是在调用此方法之前,我需要使用上传响应中的数据调用api/save。我怎样才能得到这些数据?

案例2

大部分类似的案子。用户在上传过程中停止应用程序。在几秒钟内加载应用程序,而会话处理我的任务。现在会话调用didReceiveData,但是当然,有些数据丢失了。在这种情况下我该怎么办?如何恢复响应数据?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-01-15 23:57:39

您没有提到实现URLSessionDidFinishEventsForBackgroundURLSession (一个NSURLSessionDelegate方法)。你也很想实现这一点。基本程序是:

  • 在app委托的handleEventsForBackgroundURLSession中,您应该:
代码语言:javascript
复制
- start the background `NSURLSession` (which will start receiving delegate method calls associated with all of the uploads); and 
- save the completion handler (but do not call it, yet). 

  • 然后,在URLSessionDidFinishEventsForBackgroundURLSession中(当处理完所有响应时),调用您在handleEventsForBackgroundURLSession中保存的完成处理程序。(确保将其分派到主队列。)

如果您正在执行所有这些操作,则在重新启动后台会话时,didReceiveData调用将与对各种上载的响应一起出现。

我刚刚做了一个快速测试,上传了5张20 the的图片,并立即终止了应用程序。然后,尽管应用程序没有运行,我看到服务器上缓慢地显示了这五个文件(显然是由守护进程处理的)。当完成所有五个任务时,通过app在后台透明地重新启动,调用handleEventsForBackgroundURLSession (它重新启动会话),它让所有的didReceiveData调用都被快速调用,当调用完成时,URLSessionDidFinishEventsForBackgroundURLSession被调用,我的应用程序才调用保存的完成处理程序。

至于为什么这不适用于您,没有足够的诊断问题。可能的可能性包括:

  • 也许你不恰当地终止了这个应用程序。您不能通过双击home按钮并在那里终止应用程序来关闭应用程序;您必须让它自然地自行终止,或者为了诊断/测试目的,我在代码中调用exit(0)强制它终止。
  • handleEventsForBackgroundURLSession被调用时,您可能没有重新启动会话。
  • 可能您过早地调用了提供的完成处理程序(即在调用URLSessionDidFinishEventsForBackgroundURLSession之前)。

很难说,但我怀疑在您的实现中隐藏了一些不太正确的东西,并且很难根据所提供的信息来说明它是什么(假设它不是上述要点之一)。不幸的是,调试这个后台会话非常复杂,因为当应用程序终止时,它不再附加到调试器上,因此您无法轻松地调试应用程序被iOS自动重新启动后发生的情况)。就我个人而言,我要么NSLog消息,只看设备控制台(以及监视服务器上出现的内容),要么在应用程序本身中构建一些持久的日志机制。

票数 2
EN

Stack Overflow用户

发布于 2016-02-16 09:16:38

为了测试后台会话代码,建议在实际设备上进行测试。在编写使用NSURLSession的后台会话支持的应用程序时,很容易被开发过程中三个不明显的构件所迷惑:

  • 当您从Xcode运行应用程序时,Xcode会将应用程序安装到一个新的容器中,这意味着应用程序的路径将发生变化。这可能会混淆NSURLSession的后台会话支持。备注:此问题已在iOS 9中修复;如果遇到NSURLSession无法处理iOS 9或更高版本中容器路径更改的问题,请提交错误。
  • Xcode的调试防止系统挂起应用程序。因此,如果您从Xcode运行您的应用程序,或者在启动后的某个时间附加到进程中,然后将您的应用程序移到后台,您的应用程序将继续执行,否则系统会暂停它。
  • 类似地,iOS模拟器不能准确地模拟应用程序挂起和恢复;这在过去是有效的,但在iOS 8或iOS 9模拟器中却不起作用。

来源:苹果开发者论坛

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34760265

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档