practice example data best http post error-handling nsjsonserialization swift2

http - data - swift alamofire example



Manejo de errores HTTP POST en Swift 2 (2)

Soy nuevo aquí, y esta es mi primera pregunta ... Intento escribir una aplicación en Swift 2 que realiza una solicitud HTTP POST pero no puedo averiguar cómo usar el nuevo manejo de errores de Swift 2. ¿Puede alguien hacerlo? Dígame, por favor, ¿cómo implementar el manejo de errores " hacer-intentar-capturar " de Swift 2 en el fragmento de código a continuación? (Este fragmento de código utiliza el antiguo manejo de errores de 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() }


En general, si una función throws , debe escribirla dentro de un bloque do catch o simplemente marcar la función de alcance externo (en este caso, post ) como 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() }

Si no quiere manejar estos errores directamente en su función de post , simplemente puede declararlos como throws de los que no tiene que usar do catch en absoluto.


Es probable que desee ajustar sus llamadas de NSJSONSerialization en la lógica de do / try / catch como se muestra a continuación.

En 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()

O, en 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()

También sugiero que sea un poco más cuidadoso con el desenvolvimiento forzado de data , porque desea detectar / manejar los errores, no bloquearse. Por ejemplo, arriba uso una declaración de guard para desenvolverla.