我在使用NSURLSession
框架时有一些误解,这就是为什么我决定在没有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)
我聚合所有数据
和
func URLSession(session: NSURLSession, task: NSURLSessionTask, didCompleteWithError error: NSError?)
我将此数据转换为响应对象。这个响应对象对我来说非常重要。
一切正常,而应用程序在前台,但我在后台遇到问题。
案例1
应用程序在我开始上传数据后立即崩溃。根据WWDC我需要实现
func application(application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: () -> Void)
并在didCompleteWithError
方法中调用此处理程序。但在调用此方法之前,我需要使用上传响应中的数据调用api/save
。
我怎样才能获得这些数据?
案例2
大致相似的情况。用户在上传过程中停止应用。比几秒加载应用程序,而会话适用于我的任务。现在会话调用didReceiveData
,但当然缺少一些数据。在这种情况下我该怎么办?如何恢复响应数据?
答案 0 :(得分:2)
您没有提及实施URLSessionDidFinishEventsForBackgroundURLSession
(NSURLSessionDelegate
方法)。你真的想要实现它。基本过程是:
在app delegate的handleEventsForBackgroundURLSession
中,你应该:
NSURLSession
(将开始接收与所有上传相关联的委托方法调用);和然后,在URLSessionDidFinishEventsForBackgroundURLSession
中(当您处理完所有回复后),您将调用保存在handleEventsForBackgroundURLSession
中的完成处理程序。 (确保将其分发到主队列。)
如果您正在执行所有这些操作,那么当重新启动后台会话时,didReceiveData
来电将会显示您对各种上传内容的回复。
我刚做了一个快速测试,上传了5张20mb图片并立即终止了应用。然后,即使应用程序没有运行,我看到五个文件慢慢显示在我的服务器上(显然由守护进程处理)。完成所有五个操作后,通过app在后台透明地重新启动,handleEventsForBackgroundURLSession
被调用(重新启动会话),它会让所有didReceiveData
调用快速被调用,并在完成时完成,URLSessionDidFinishEventsForBackgroundURLSession
被调用,我的应用程序只调用已保存的完成处理程序。
就为什么这对你不起作用而言,还不足以诊断问题。可能性包括:
也许您不恰当地终止了该应用。你不能通过双击主页按钮并在那里终止应用程序来杀死应用程序;你必须让它自然地终止它,或者出于诊断/测试目的,我强制它通过在代码中调用exit(0)
来终止。
在调用handleEventsForBackgroundURLSession
时,您可能没有重启会话。
也许您过早地调用了提供的完成处理程序(即在调用URLSessionDidFinishEventsForBackgroundURLSession
之前)。
很难说,但我怀疑你的实施中埋藏了一些不太正确的东西,根据所提供的信息很难说它是什么(假设它不是上述点之一)。不幸的是,调试这些后台会话非常复杂,因为当应用程序终止时,它不再附加到调试器,因此您无法轻松调试iOS自动重启应用程序后发生的情况。就个人而言,我要么NSLog
消息,只是观察设备控制台(以及观察服务器上显示的内容),或者我在应用程序本身中构建了一些持久性日志记录机制。
答案 1 :(得分:0)
为了测试后台会话代码,建议在真实设备上进行测试。在编写使用NSURLSession的后台会话支持的应用程序时,很容易被开发过程的三个非显而易见的工件搞糊涂: