【问题标题】:How to handle losing Internet connection with NSURLSession?如何使用 NSURLSession 处理丢失的 Internet 连接?
【发布时间】:2015-12-17 17:10:28
【问题描述】:


我正在使用 NSURL 从网站上抓取 HTML。问题是,如果在 NSURL 请求期间互联网中断,应用程序就会崩溃。
代码:

let myUrl = NSURL(string: "http://www.mywebsite.com/page.html")
let request = NSMutableURLRequest(URL: myUrl!)
request.HTTPMethod = "POST"
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
    data, response, error in
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)) {
        let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)
        if error != nil {
             print("Error: \(error)")
        } 
        dispatch_async(dispatch_get_main_queue()) {
            self.testLabel.text = "\(responseString!)"
        }
    }
}
task.resume()

我可以使用此代码在 NSURL 连接之前检查互联网连接,但是在操作过程中仍有可能断开互联网:
在 NSURL 之前检查互联网连接的代码:

let myUrl = NSURL(string: "http://www.mywebsite.com/page.html")
let request = NSMutableURLRequest(URL: myUrl!)
request.HTTPMethod = "POST"
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
    data, response, error in
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)) {
        let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)
        if error != nil {
             print("Error: \(error)")
        } 
        dispatch_async(dispatch_get_main_queue()) {
            self.testLabel.text = "\(responseString!)"
        }
    }
}
task.resume()

为了解决这个问题,我使用 try/catch 操作进行了研究,但是我没有成功构建一个不会给我错误的操作。有没有办法将整个 NSURL 操作包装在一个巨大的 try/catch 中以捕获任何错误?我在想一些类似的事情,但它不起作用:
代码:

let myUrl = NSURL(string: "http://www.mywebsite.com/page.html")
let request = NSMutableURLRequest(URL: myUrl!)
request.HTTPMethod = "POST"
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
        data, response, error in
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)) {
    let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)
    if error != nil {
         print("Error: \(error)")
    } 
    dispatch_async(dispatch_get_main_queue()) {
        self.testLabel.text = "\(responseString!)"
    }
  }
}
task.resume()
} catch {
    timer.invalidate
    sendAlert("Error", message: "You are not connected to the internet")
}

【问题讨论】:

  • 看起来你想要像Reachability这样的东西
  • 使用保护解开数据 let data = data where error == nil else { return }
  • 在检查错误之前,您正在对data(例如data!)进行强制解包。除非你知道它永远不可能是nil,否则永远不要强制展开。否则你会崩溃。因此,正如 Leo 建议的那样,添加一些错误处理以确保 data 不是 nil 并且 errornil

标签: ios swift nsurlsession


【解决方案1】:

! 的正确发音是“我对我的程序的生命发誓”。因为这就是你正在做的事情。为什么你觉得你必须使用!?使用guard-let 为您解决所有问题:

    let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
        data, response, error in

        guard error == nil else {
            print("Error: \(error)")
            return
        }

        guard let data = data else {
            fatalError("error was nil, but no data. This should never happen")
        }

        guard let responseString = NSString(data: data, encoding: NSUTF8StringEncoding) else {
            print("Couldn't decode data")
            return
        }

        dispatch_async(dispatch_get_main_queue()) {
            self.testLabel.text = "\(responseString)"
        }
    }

【讨论】:

    【解决方案2】:

    只有当你知道 100% 有一个值时,你才应该强制解包变量,否则你会导致你的应用程序崩溃。如果您需要这方面的更多信息,您应该查看The Swift Programming Language guide 的可选链接部分

    用于检查

    下面的代码应该适合你。

        let myUrl = NSURL(string: "http://www.mywebsite.com/page.html")
        let request = NSMutableURLRequest(URL: myUrl!)
        request.HTTPMethod = "POST"
        let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
            data, response, error in
            dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)) {
    
                if let responseData = data {
    
                    let responseString = NSString(data: responseData, encoding: NSUTF8StringEncoding)
                    if error != nil {
                        print("Error: \(error)")
                    }
                    dispatch_async(dispatch_get_main_queue()) {
                        print("Response: \(responseString!)")
                    }
                }
    
            }
        }
    
        task.resume()
    

    在处理您的互联网连接故障方面,您应该检查关闭时发回的响应并决定您要采取的行动方案。

        if let httpResponse = response as? NSHTTPURLResponse {
        println("error \(httpResponse.statusCode)")
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-01-14
      • 2018-01-30
      • 1970-01-01
      • 1970-01-01
      • 2020-04-05
      • 1970-01-01
      • 2014-05-03
      相关资源
      最近更新 更多