使用 NSURLSession 后台配置检测 DNS 故障?
Detecting DNS failure with NSURLSession background config?
在后台配置中使用 NSURLSession
时是否可以检测 DNS 查找失败?
如果我使用默认配置和完成处理程序,错误参数中会报告 DNS 解析失败。但是,如果我使用后台配置,则永远不会报告失败,也不会调用委托方法。
NSURLSessionTaskDelegate
协议的 Apple 文档说:
Server errors are not reported through the error parameter. The only
errors your delegate receives through the error parameter are
client-side errors, such as being unable to resolve the hostname or
connect to the host.
这表明我应该在那里看到 DNS 故障消息。下面的代码说明了这种行为。我已经在设备和模拟器上对 iOS 8.4 和 9 进行了测试,并搜索了开发论坛,因此并使用了流行的搜索引擎,但结果是空的。我确定我一定遗漏了一些非常简单的东西。
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, NSURLSessionTaskDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
let bgsesh = NSURLSession(configuration: NSURLSessionConfiguration.backgroundSessionConfigurationWithIdentifier("foobarbazqwux"), delegate: self, delegateQueue: nil)
let dfsesh = NSURLSession(configuration: NSURLSessionConfiguration.defaultSessionConfiguration(), delegate: nil, delegateQueue: nil)
let url = NSURL(string: "http://foobarbaz.qwzx")!
let a = dfsesh.downloadTaskWithURL(url) { (url:NSURL?, resp:NSURLResponse?, err:NSError?) -> Void in
print(err)
/*
Optional(Error Domain=NSURLErrorDomain Code=-1003
"A server with the specified hostname could not be found."
UserInfo=0x146e8050 {
NSErrorFailingURLStringKey=http://foobarbaz.qwzx/,
_kCFStreamErrorCodeKey=8,
NSErrorFailingURLKey=http://foobarbaz.qwzx/,
NSLocalizedDescription=A server with the specified hostname could not be found.,
_kCFStreamErrorDomainKey=12,
NSUnderlyingError=0x14693ab0 "The operation couldn’t be completed. (kCFErrorDomainCFNetwork error -1003.)"
})
*/
}
a.resume()
let b = bgsesh.downloadTaskWithURL(url)
b.resume()
return true
}
func URLSession(session: NSURLSession, task: NSURLSessionTask, didCompleteWithError error: NSError?) {
// never runs, DNS failure is not reported for background config :-(
print("didCompleteWithError: \(task.taskIdentifier) \(error)")
}
// ... other delegate methods ...
}
设置URLSessionConfiguration.timeoutIntervalForResource
.
The resource timeout interval controls how long (in seconds) to wait for an entire resource to transfer before giving up.
The default value is 7 days.
例如,
let conf = NSURLSessionConfiguration.backgroundSessionConfigurationWithIdentifier("foobarbazqwux")
conf.timeoutIntervalForResource = 60 // seconds
let session = NSURLSession(configuration: conf, delegate: self, delegateQueue: nil)
在这种情况下,如果 60 秒后仍然失败,系统将重试连接并调用委托。
根据@algrid 的评论进行编辑:
这个值应该考虑到资源的传输时间。因此,它取决于 download/upload 的资源大小和网络速度。
在后台配置中使用 NSURLSession
时是否可以检测 DNS 查找失败?
如果我使用默认配置和完成处理程序,错误参数中会报告 DNS 解析失败。但是,如果我使用后台配置,则永远不会报告失败,也不会调用委托方法。
NSURLSessionTaskDelegate
协议的 Apple 文档说:
Server errors are not reported through the error parameter. The only errors your delegate receives through the error parameter are client-side errors, such as being unable to resolve the hostname or connect to the host.
这表明我应该在那里看到 DNS 故障消息。下面的代码说明了这种行为。我已经在设备和模拟器上对 iOS 8.4 和 9 进行了测试,并搜索了开发论坛,因此并使用了流行的搜索引擎,但结果是空的。我确定我一定遗漏了一些非常简单的东西。
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, NSURLSessionTaskDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
let bgsesh = NSURLSession(configuration: NSURLSessionConfiguration.backgroundSessionConfigurationWithIdentifier("foobarbazqwux"), delegate: self, delegateQueue: nil)
let dfsesh = NSURLSession(configuration: NSURLSessionConfiguration.defaultSessionConfiguration(), delegate: nil, delegateQueue: nil)
let url = NSURL(string: "http://foobarbaz.qwzx")!
let a = dfsesh.downloadTaskWithURL(url) { (url:NSURL?, resp:NSURLResponse?, err:NSError?) -> Void in
print(err)
/*
Optional(Error Domain=NSURLErrorDomain Code=-1003
"A server with the specified hostname could not be found."
UserInfo=0x146e8050 {
NSErrorFailingURLStringKey=http://foobarbaz.qwzx/,
_kCFStreamErrorCodeKey=8,
NSErrorFailingURLKey=http://foobarbaz.qwzx/,
NSLocalizedDescription=A server with the specified hostname could not be found.,
_kCFStreamErrorDomainKey=12,
NSUnderlyingError=0x14693ab0 "The operation couldn’t be completed. (kCFErrorDomainCFNetwork error -1003.)"
})
*/
}
a.resume()
let b = bgsesh.downloadTaskWithURL(url)
b.resume()
return true
}
func URLSession(session: NSURLSession, task: NSURLSessionTask, didCompleteWithError error: NSError?) {
// never runs, DNS failure is not reported for background config :-(
print("didCompleteWithError: \(task.taskIdentifier) \(error)")
}
// ... other delegate methods ...
}
设置URLSessionConfiguration.timeoutIntervalForResource
.
The resource timeout interval controls how long (in seconds) to wait for an entire resource to transfer before giving up.
The default value is 7 days.
例如,
let conf = NSURLSessionConfiguration.backgroundSessionConfigurationWithIdentifier("foobarbazqwux")
conf.timeoutIntervalForResource = 60 // seconds
let session = NSURLSession(configuration: conf, delegate: self, delegateQueue: nil)
在这种情况下,如果 60 秒后仍然失败,系统将重试连接并调用委托。
根据@algrid 的评论进行编辑:
这个值应该考虑到资源的传输时间。因此,它取决于 download/upload 的资源大小和网络速度。