NSURLSessionUploadTask 获取响应数据 [英] NSURLSessionUploadTask get response data

查看:70
本文介绍了NSURLSessionUploadTask 获取响应数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have some misunderstanding in using NSURLSession framework, that's why I decided to write small app from scratch without AFFramework/Alamofire.

我有一个 API,需要执行以下步骤才能上传文件:

I have an API that requires following steps to upload file:

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

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

I have a background session with such config:

let configuration = NSURLSessionConfiguration.backgroundSessionConfigurationWithIdentifier("myBackground")
let session = NSURLSession(configuration: configuration, delegate: self, delegateQueue: nil)

我已经实现了两种方法:

I've implemented 2 methods:

func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveData data: NSData)

我汇总所有数据的地方

func URLSession(session: NSURLSession, task: NSURLSessionTask, didCompleteWithError error: NSError?)

我将这些数据转换为响应对象的地方.这个响应对象对我来说非常重要.

where I tranform this data to response object. This response object if VERY important for me.

一切正常,而应用程序在前台,但我在后台遇到问题.

Everything works fine, while app is in foreground, but I have problems in background.

案例 1

应用在我开始上传数据后立即崩溃.根据WWDC,我需要实施

App crashed right after I've started to upload data. According to WWDC I need to implement

func application(application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: () -> Void)

并在 didCompleteWithError 方法中调用此处理程序.但在调用此方法之前,我需要使用上传响应中的数据调用 api/save.我如何获得这些数据?

and call this handler in didCompleteWithError method. But before calling this method I need to call api/save with data from upload response. How can I get this data?

案例 2

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

Mostly similar case. User stops app while upload is in progress. Than loads app in few seconds, while session works with my task. Now session calls didReceiveData, but of course, some of data is missing. What should I do in such case? How to restore response data?

推荐答案

你没有提到实现 URLSessionDidFinishEventsForBackgroundURLSession(一个 NSURLSessionDelegate 方法).你也真的想实现它.基本流程是:

You don't mention implementing URLSessionDidFinishEventsForBackgroundURLSession (a NSURLSessionDelegate method). You really want to implement that, too. The basic process is:

  • 在应用委托的handleEventsForBackgroundURLSession中,您应该:

  • 启动后台NSURLSession(它将开始接收与所有上传相关的委托方法调用);和
  • 保存完成处理程序(但暂时不要调用它).
  • 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 中的完成处理程序.(确保将其分派到主队列.)

Then, in URLSessionDidFinishEventsForBackgroundURLSession (when you're done processing all of the responses), you call the completion handler you saved in handleEventsForBackgroundURLSession. (Make sure to dispatch that to the main queue.)

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

If you're doing all of that, when the background session is restarted, the didReceiveData calls will come in with the responses to your various uploads.

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

I just did a quick test, uploading five 20mb images and immediately terminating the app. Then, even though the app wasn't running, I watched the five files slowly show up on my server (obviously handled by the daemon process). When all five were done, by app was transparently restarted in the background, the handleEventsForBackgroundURLSession was called (which restarted the session), it let all of the didReceiveData calls quickly get called, and when that was done, URLSessionDidFinishEventsForBackgroundURLSession was called and my app only then called the saved completion handler.

就为什么这对您不起作用而言,还不足以诊断问题.可能性包括:

In terms of why this isn't working for you, there's not enough to diagnose the problem. Possibilities include:

  • 也许你不恰当地终止了应用程序.你不能通过双击主页按钮并在那里终止应用程序来终止应用程序;你必须让它自己自然终止,或者为了诊断/测试目的,我通过在代码中调用 exit(0) 来强制它终止.

也许在调用 handleEventsForBackgroundURLSession 时您没有重新启动会话.

Maybe you didn't restart the session when handleEventsForBackgroundURLSession was called.

也许您过早地调用了提供的完成处理程序(即在调用 URLSessionDidFinishEventsForBackgroundURLSession 之前).

Maybe you called the supplied completion handler too soon (i.e. before URLSessionDidFinishEventsForBackgroundURLSession was called).

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

It's hard to say, but I suspect that there's something buried inside your implementation that isn't quite right and it's hard to say what it is on the basis of the information provided (assuming it isn't one of the above points). Unfortunately, debugging this background sessions is vexingly complicated because when the app terminates, it is no longer attached to the debugger, so you can't easily debug what happens after the app is restarted automatically by iOS). Personally, I either NSLog messages and just watch the device console (as well as watching what appears on the server), or I build some persistent logging mechanism into the app itself.

这篇关于NSURLSessionUploadTask 获取响应数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆