我有一个用Swift 1.2编写的函数,它检查地址或IP的可达性。这是:
func isHostConnected(hostAddress : String) -> Bool
{
var response : NSURLResponse?
let request = NSMutableURLRequest(URL: NSURL(string: hostAddress)!)
request.timeoutInterval = 3
let data = NSURLConnection.sendSynchronousRequest(request, returningResponse: &response, error: nil)
return ((response as? NSHTTPURLResponse)!.statusCode == 200)
}
现在,NSURLConnection
已被弃用,根据Xcode建议,我尝试使用NSURLSession.dataTaskWithRequest
编写它,这里是:
func isHostConnected(hostAddress : String) -> Bool
{
let request = NSMutableURLRequest(URL: NSURL(string: hostAddress.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)!)!)
request.timeoutInterval = 3
let session = NSURLSession(configuration: NSURLSessionConfiguration.defaultSessionConfiguration(), delegate: nil, delegateQueue: NSOperationQueue.mainQueue())
var responseCode = -1
session.dataTaskWithRequest(request, completionHandler: {(data : NSData?, response : NSURLResponse?, error : NSError?) -> Void in
responseCode = (response as? NSHTTPURLResponse)!.statusCode
})!.resume()
return (responseCode == 200)
}
上面的代码总是返回 false (显而易见),因为completionHandler
会在单独的线程上执行。
我担心的是,我是否可以通过阻止它来completionHandler()
以sendSynchronousRequest
的方式在MainThread上运行。
我有理由不使用Apple的Reachabilty'这里。
任何建议都会有所帮助。 :)
答案 0 :(得分:11)
(从https://stackoverflow.com/a/30670518/1187415重复我的论点:)
检查服务器上是否存在资源需要发送HTTP 请求并收到回复。 TCP通信可能需要一些 时间量,例如如果服务器忙,一些路由器之间 客户端和服务器无法正常工作,网络已关闭 等
这就是为什么异步请求总是首选的原因。即使你 认为请求应该只需要几毫秒,它可能 由于某些网络问题,有时会是秒。而且 - 像我们一样 知道 - 阻塞主线程几秒钟是一个很大的禁忌。
话虽这么说,你可以使用"计数信号量"或者一个"派遣小组"等待一些异步任务的完成。 你应该不在主线程上使用它。阻止主线程 最长3秒是不可接受的!
func isHostConnected(hostAddress : String) -> Bool
{
let request = NSMutableURLRequest(URL: NSURL(string: hostAddress.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)!)!)
request.timeoutInterval = 3
request.HTTPMethod = "HEAD"
let session = NSURLSession(configuration: NSURLSessionConfiguration.defaultSessionConfiguration())
var responseCode = -1
let group = dispatch_group_create()
dispatch_group_enter(group)
session.dataTaskWithRequest(request, completionHandler: {(_, response, _) in
if let httpResponse = response as? NSHTTPURLResponse {
responseCode = httpResponse.statusCode
}
dispatch_group_leave(group)
})!.resume()
dispatch_group_wait(group, DISPATCH_TIME_FOREVER)
return (responseCode == 200)
}
说明:
response
将是nil
,并且。{
responseCode = (response as? NSHTTPURLResponse)!.statusCode
会崩溃。