【问题标题】:HTTP POST error Handling in Swift 2Swift 2 中的 HTTP POST 错误处理
【发布时间】:2015-09-10 21:07:54
【问题描述】:

我是新来的,这是我的第一个问题... 我尝试在 Swift 2 中编写一个发出 HTTP POST 请求的应用程序,但我不知道如何使用 Swift 2 的新错误处理。谁能告诉我如何实现“do-try- catch" Swift 2 的错误处理到下面的代码 sn-p? (这段代码sn-p使用了swift 1.2旧的错误处理)

func post(params : Dictionary<String, String>, url : String) {
    var request = NSMutableURLRequest(URL: NSURL(string: url)!)
    var session = NSURLSession.sharedSession()
    request.HTTPMethod = "POST"

    var err: NSError?
    request.HTTPBody = NSJSONSerialization.dataWithJSONObject(params, options: nil/*, error: &err*/)
    request.addValue("application/json", forHTTPHeaderField: "Content-Type")
    request.addValue("application/json", forHTTPHeaderField: "Accept")

    var task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in
        print("Response: \(response)")
        var strData = NSString(data: data!, encoding: NSUTF8StringEncoding)
        print("Body: \(strData)")
        var err: NSError?
        var json = NSJSONSerialization.JSONObjectWithData(data!, options: .MutableLeaves/*, error: &err*/) as? NSDictionary

        // Did the JSONObjectWithData constructor return an error? If so, log the error to the console
        if(err != nil) {
            print(err!.localizedDescription)
            let jsonStr = NSString(data: data!, encoding: NSUTF8StringEncoding)
            print("Error could not parse JSON: '\(jsonStr)'")
        }
        else {
            // The JSONObjectWithData constructor didn't return an error. But, we should still
            // check and make sure that json has a value using optional binding.
            if let parseJSON = json {
                // Okay, the parsedJSON is here, let's get the value for 'success' out of it
                var success = parseJSON["success"] as? Int
                print("Succes: \(success)")
            }
            else {
                // Woa, okay the json object was nil, something went worng. Maybe the server isn't running?
                let jsonStr = NSString(data: data!, encoding: NSUTF8StringEncoding)
                print("Error could not parse JSON: \(jsonStr)")
            }
        }
    })

    task!.resume()
}

【问题讨论】:

    标签: http post error-handling nsjsonserialization swift2


    【解决方案1】:

    您可能希望将您的NSJSONSerialization 调用包装在do/try/catch 逻辑中,如下所示。

    在 Swift 3 中:

    var request = URLRequest(url: URL(string: urlString)!)
    
    let session = URLSession.shared
    request.httpMethod = "POST"
    request.addValue("application/json", forHTTPHeaderField: "Content-Type")
    request.addValue("application/json", forHTTPHeaderField: "Accept")
    
    request.httpBody = try! JSONSerialization.data(withJSONObject: parameters)
    
    // or if you think the conversion might actually fail (which is unlikely if you built `parameters` yourself)
    //
    // do {
    //    request.httpBody = try JSONSerialization.data(withJSONObject: parameters)
    // } catch {
    //    print(error)
    // }
    
    let task = session.dataTask(with: request) { data, response, error in
        guard let data = data, error == nil else {
            print("error: \(error)")
            return
        }
    
        // this, on the other hand, can quite easily fail if there's a server error, so you definitely
        // want to wrap this in `do`-`try`-`catch`:
    
        do {
            if let json = try JSONSerialization.jsonObject(with: data) as? [String: Any] {
                let success = json["success"] as? Int                                  // Okay, the `json` is here, let's get the value for 'success' out of it
                print("Success: \(success)")
            } else {
                let jsonStr = String(data: data, encoding: .utf8)    // No error thrown, but not dictionary
                print("Error could not parse JSON: \(jsonStr)")
            }
        } catch let parseError {
            print(parseError)                                                          // Log the error thrown by `JSONObjectWithData`
            let jsonStr = String(data: data, encoding: .utf8)
            print("Error could not parse JSON: '\(jsonStr)'")
        }
    }
    
    task.resume()
    

    或者,在 Swift 2 中

    let request = NSMutableURLRequest(URL: NSURL(string: urlString)!)
    
    let session = NSURLSession.sharedSession()
    request.HTTPMethod = "POST"
    request.addValue("application/json", forHTTPHeaderField: "Content-Type")
    request.addValue("application/json", forHTTPHeaderField: "Accept")
    
    request.HTTPBody = try! NSJSONSerialization.dataWithJSONObject(parameters, options: [])
    
    // or if you think the conversion might actually fail (which is unlikely if you built `parameters` yourself)
    //
    // do {
    //    request.HTTPBody = try NSJSONSerialization.dataWithJSONObject(params, options: [])
    // } catch {
    //    print(error)
    // }
    
    let task = session.dataTaskWithRequest(request) { data, response, error in
        guard let data = data where error == nil else {
            print("error: \(error)")
            return
        }
    
        // this, on the other hand, can quite easily fail if there's a server error, so you definitely
        // want to wrap this in `do`-`try`-`catch`:
    
        do {
            if let json = try NSJSONSerialization.JSONObjectWithData(data, options: []) as? NSDictionary {
                let success = json["success"] as? Int                                  // Okay, the `json` is here, let's get the value for 'success' out of it
                print("Success: \(success)")
            } else {
                let jsonStr = String(data: data, encoding: NSUTF8StringEncoding)    // No error thrown, but not NSDictionary
                print("Error could not parse JSON: \(jsonStr)")
            }
        } catch let parseError {
            print(parseError)                                                          // Log the error thrown by `JSONObjectWithData`
            let jsonStr = String(data: data, encoding: NSUTF8StringEncoding)
            print("Error could not parse JSON: '\(jsonStr)'")
        }
    }
    
    task.resume()
    

    我还建议对data 的强制解包更加小心,因为您想要检测/处理错误,而不是崩溃。例如,上面我使用guard 语句来解包。

    【讨论】:

      【解决方案2】:

      一般来说,如果一个函数 throws 你必须将它写在一个 do catch 块中,或者只是将外部范围函数(在本例中为 post)标记为 throws

      func post(params : Dictionary<String, String>, url : String) {
          let request = NSMutableURLRequest(URL: NSURL(string: url)!)
          let session = NSURLSession.sharedSession()
          request.HTTPMethod = "POST"
      
          do {
              request.HTTPBody = try NSJSONSerialization.dataWithJSONObject(params, options: .PrettyPrinted)
          } catch {
              //handle error. Probably return or mark function as throws
              print(error)
              return
          }
          request.addValue("application/json", forHTTPHeaderField: "Content-Type")
          request.addValue("application/json", forHTTPHeaderField: "Accept")
      
          let task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in
              // handle error
              guard error == nil else { return }
      
              print("Response: \(response)")
              let strData = NSString(data: data!, encoding: NSUTF8StringEncoding)
              print("Body: \(strData)")
      
              let json: NSDictionary?
              do {
                  json = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableLeaves) as? NSDictionary
              } catch let dataError {
                  // Did the JSONObjectWithData constructor return an error? If so, log the error to the console
                  print(dataError)
                  let jsonStr = NSString(data: data!, encoding: NSUTF8StringEncoding)
                  print("Error could not parse JSON: '\(jsonStr)'")
                  // return or throw?
                  return
              }
      
      
              // The JSONObjectWithData constructor didn't return an error. But, we should still
              // check and make sure that json has a value using optional binding.
              if let parseJSON = json {
                  // Okay, the parsedJSON is here, let's get the value for 'success' out of it
                  let success = parseJSON["success"] as? Int
                  print("Succes: \(success)")
              }
              else {
                  // Woa, okay the json object was nil, something went worng. Maybe the server isn't running?
                  let jsonStr = NSString(data: data!, encoding: NSUTF8StringEncoding)
                  print("Error could not parse JSON: \(jsonStr)")
              }
      
          })
      
          task!.resume()
      }
      

      如果您不想在 post 函数中直接处理这些错误,您可以将其声明为 throws,而不是根本不必使用 do catch

      【讨论】:

        猜你喜欢
        • 2015-12-24
        • 1970-01-01
        • 2016-08-02
        • 2015-09-06
        • 2017-12-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多