具有后台配置的 NSURLSession 和被用户杀死的应用程序
NSURLSession with background configuration and app killed by user
场景是这样的:
- 带后台配置的NSURLSession
- 下载或上传任务以错误或无互联网连接开始。
- 用户关闭应用程序。
- 如果iOS获取互联网连接将启动会话任务。然而,
- 任务仍在等待 Internet。
- 用户终止应用程序
- 系统取消所有挂起的任务
问题
是否可以在用户再次打开应用时知道任务被取消了?
如果是,在哪里?
This Answer 说是的,这是可能的,但我无法得到任何返回错误的回调。
我正在使用 Alamofire 来处理我所有的网络调用。但是,我怀疑 Alamofire 会改变这种行为。
编辑 1
/// Networking manager with Background Session Configuration
static var backgroundManager: Alamofire.Manager = {
let configuration = NSURLSessionConfiguration.backgroundSessionConfigurationWithIdentifier("com.xxx.NetworkingManager.Identifier")
configuration.HTTPAdditionalHeaders = Manager.defaultHTTPHeaders
let backgroundManager = Alamofire.Manager(configuration: configuration)
return backgroundManager
}()
感谢 Rob,因为他为我指明了正确的道路。
所以用户杀掉应用后,系统会取消所有挂起的任务。
你可以看到 system.log:
Simulator/Debug/Open System Log...
如何捕捉已经发生的事情?
再次实例化您的背景NSURLSession
。在别处进行,但我将在 AppDelegate 中进行此示例。
系统知道(由于标识符)它是与之前相同的后台会话,因此它映射未决任务。
然后检索所有任务。取消的任务还在
任务将有错误,您可以检查。
Error Domain=NSURLErrorDomain Code=-999 "(null)"
UserInfo={NSErrorFailingURLStringKey=http://your.api.com/url,
NSURLErrorBackgroundTaskCancelledReasonKey=0,
NSErrorFailingURLKey=http://your.api.com/url}
此外,通过任务,您将获得请求 URL,因此您可以映射您的应用请求并执行某些操作。
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// This is the code for Swift 2.x. In Swift 3.x this call is a bit different.
NetworkingManager.backgroundManager.session.getTasksWithCompletionHandler { (data, upload, download) in
for task in data {
NSLog("\(task.error)")
}
for task in upload {
NSLog("\(task.error)")
}
for task in download {
NSLog("\(task.error)")
let reason = task.error?.userInfo[NSURLErrorBackgroundTaskCancelledReasonKey] as? Int
let code = task.error?.code
if reason == NSURLErrorCancelledReasonUserForceQuitApplication &&
code == NSURLErrorCancelled {
NSLog("\(task.originalRequest)")
NSLog("\(task.currentRequest?.URL)")
}
}
}
}
NSURLErrorCancelledReasonUserForceQuitApplication
-> 操作被取消,因为用户强制退出应用程序。
所以我们走在正确的轨道上。
如果有人有更好的解决方案,请分享!我不太喜欢我的请求 url 的映射解决方案。
场景是这样的:
- 带后台配置的NSURLSession
- 下载或上传任务以错误或无互联网连接开始。
- 用户关闭应用程序。
- 如果iOS获取互联网连接将启动会话任务。然而,
- 任务仍在等待 Internet。
- 用户终止应用程序
- 系统取消所有挂起的任务
问题
是否可以在用户再次打开应用时知道任务被取消了?
如果是,在哪里?
This Answer 说是的,这是可能的,但我无法得到任何返回错误的回调。
我正在使用 Alamofire 来处理我所有的网络调用。但是,我怀疑 Alamofire 会改变这种行为。
编辑 1
/// Networking manager with Background Session Configuration
static var backgroundManager: Alamofire.Manager = {
let configuration = NSURLSessionConfiguration.backgroundSessionConfigurationWithIdentifier("com.xxx.NetworkingManager.Identifier")
configuration.HTTPAdditionalHeaders = Manager.defaultHTTPHeaders
let backgroundManager = Alamofire.Manager(configuration: configuration)
return backgroundManager
}()
感谢 Rob,因为他为我指明了正确的道路。
所以用户杀掉应用后,系统会取消所有挂起的任务。
你可以看到 system.log:
Simulator/Debug/Open System Log...
如何捕捉已经发生的事情?
再次实例化您的背景NSURLSession
。在别处进行,但我将在 AppDelegate 中进行此示例。
系统知道(由于标识符)它是与之前相同的后台会话,因此它映射未决任务。
然后检索所有任务。取消的任务还在
任务将有错误,您可以检查。
Error Domain=NSURLErrorDomain Code=-999 "(null)"
UserInfo={NSErrorFailingURLStringKey=http://your.api.com/url,
NSURLErrorBackgroundTaskCancelledReasonKey=0,
NSErrorFailingURLKey=http://your.api.com/url}
此外,通过任务,您将获得请求 URL,因此您可以映射您的应用请求并执行某些操作。
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// This is the code for Swift 2.x. In Swift 3.x this call is a bit different.
NetworkingManager.backgroundManager.session.getTasksWithCompletionHandler { (data, upload, download) in
for task in data {
NSLog("\(task.error)")
}
for task in upload {
NSLog("\(task.error)")
}
for task in download {
NSLog("\(task.error)")
let reason = task.error?.userInfo[NSURLErrorBackgroundTaskCancelledReasonKey] as? Int
let code = task.error?.code
if reason == NSURLErrorCancelledReasonUserForceQuitApplication &&
code == NSURLErrorCancelled {
NSLog("\(task.originalRequest)")
NSLog("\(task.currentRequest?.URL)")
}
}
}
}
NSURLErrorCancelledReasonUserForceQuitApplication
-> 操作被取消,因为用户强制退出应用程序。
所以我们走在正确的轨道上。 如果有人有更好的解决方案,请分享!我不太喜欢我的请求 url 的映射解决方案。