【问题标题】:Fixing NSURLConnection Deprecation from Swift 1.2 to 2.0修复从 Swift 1.2 到 2.0 的 NSURLConnection 弃用
【发布时间】:2015-06-20 08:10:28
【问题描述】:

我有一个用 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() 在 MainThread 上运行,就像 sendSynchronousRequest 那样通过阻止它来运行。

我有理由不在这里使用“Apple's Reachabilty”。

任何建议都会有所帮助。 :)

【问题讨论】:

    标签: swift xcode7 swift2 ios9


    【解决方案1】:

    (从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)
    }
    

    备注:

    • 将 HTTP 方法设置为“HEAD”是一个小的优化,因为 服务器只发送响应头而不发送实际数据。
    • 如果主机名非法,response 将是 nil,并且 responseCode = (response as? NSHTTPURLResponse)!.statusCode 会崩溃。

    【讨论】:

    • 哇......我不知道像dispatch_group 这样的东西,肯定会探索这个& thnxxx 很多,@Martin。
    猜你喜欢
    • 1970-01-01
    • 2016-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-16
    • 1970-01-01
    • 2015-10-17
    相关资源
    最近更新 更多