example - Swift Alamofire: cómo obtener el código de estado de respuesta HTTP
swiftyjson alamofire (9)
La mejor manera de obtener el código de estado usando alamofire.
Alamofire.request(URL).responseJSON { response in let status = response.response?.statusCode print("STATUS /(status)") }
Me gustaría recuperar el código de estado de respuesta HTTP (p. Ej., 400, 401, 403, 503, etc.) para los fallos de solicitud (e idealmente para los éxitos también). En este código, realizo la autenticación de usuario con HTTP Basic y deseo poder enviarle un mensaje al usuario de que la autenticación falló cuando el usuario escribe incorrectamente su contraseña.
Alamofire.request(.GET, "https://host.com/a/path").authenticate(user: "user", password: "typo")
.responseString { (req, res, data, error) in
if error != nil {
println("STRING Error:: error:/(error)")
println(" req:/(req)")
println(" res:/(res)")
println(" data:/(data)")
return
}
println("SUCCESS for String")
}
.responseJSON { (req, res, data, error) in
if error != nil {
println("JSON Error:: error:/(error)")
println(" req:/(req)")
println(" res:/(res)")
println(" data:/(data)")
return
}
println("SUCCESS for JSON")
}
Desafortunadamente, el error producido no parece indicar que realmente se recibió un código de estado HTTP 409:
STRING Error:: error:Optional(Error Domain=NSURLErrorDomain Code=-999 "cancelled" UserInfo=0x7f9beb8efce0 {NSErrorFailingURLKey=https://host.com/a/path, NSLocalizedDescription=cancelled, NSErrorFailingURLStringKey=https://host.com/a/path})
req:<NSMutableURLRequest: 0x7f9beb89d5e0> { URL: https://host.com/a/path }
res:nil
data:Optional("")
JSON Error:: error:Optional(Error Domain=NSURLErrorDomain Code=-999 "cancelled" UserInfo=0x7f9beb8efce0 {NSErrorFailingURLKey=https://host.com/a/path, NSLocalizedDescription=cancelled, NSErrorFailingURLStringKey=https://host.com/a/path})
req:<NSMutableURLRequest: 0x7f9beb89d5e0> { URL: https://host.com/a/path }
res:nil
data:nil
Además, sería bueno recuperar el cuerpo HTTP cuando se produce un error porque mi lado del servidor pondrá una descripción textual del error allí.
Preguntas
¿Es posible recuperar el código de estado en una respuesta que no sea 2xx?
¿Es posible recuperar el código de estado específico en una respuesta 2xx?
¿Es posible recuperar el cuerpo HTTP en una respuesta que no sea 2xx?
¡Gracias!
Al completar la
responseJSON
JSON, puede obtener el código de estado del objeto de respuesta, que tiene un tipo de
NSHTTPURLResponse?
:
if let response = res {
var statusCode = response.statusCode
}
Esto funcionará independientemente de si el código de estado está en el rango de error. Para obtener más información, consulte la documentación de NSHTTPURLResponse .
Para su otra pregunta, puede usar la función
responseString
para obtener el cuerpo de respuesta sin procesar.
Puede agregar esto además de
responseJSON
y se llamarán a ambos.
.responseJson { (req, res, json, error) in
// existing code
}
.responseString { (_, _, body, _) in
// body is a String? containing the response body
}
En el controlador de finalización con
response
argumento a continuación, encuentro que el código de estado http está en
response.response.statusCode
:
Alamofire.request(.POST, urlString, parameters: parameters)
.responseJSON(completionHandler: {response in
switch(response.result) {
case .Success(let JSON):
// Yeah! Hand response
case .Failure(let error):
let message : String
if let httpStatusCode = response.response?.statusCode {
switch(httpStatusCode) {
case 400:
message = "Username or password not provided."
case 401:
message = "Incorrect password for user ''/(name)''."
...
}
} else {
message = error.localizedDescription
}
// display alert with error message
}
O use la coincidencia de patrones
if let error = response.result.error as? AFError {
if case .responseValidationFailed(.unacceptableStatusCode(let code)) = error {
print(code)
}
}
Para usuarios de Swift 3.x / Swift 4.0 / Swift 5.0 con Alamofire> = 4.0 / Alamofire> = 5.0
response.response?.statusCode
Ejemplo más detallado:
Alamofire.request(urlString)
.responseString { response in
print("Success: /(response.result.isSuccess)")
print("Response String: /(response.result.value)")
var statusCode = response.response?.statusCode
if let error = response.result.error as? AFError {
statusCode = error._code // statusCode private
switch error {
case .invalidURL(let url):
print("Invalid URL: /(url) - /(error.localizedDescription)")
case .parameterEncodingFailed(let reason):
print("Parameter encoding failed: /(error.localizedDescription)")
print("Failure Reason: /(reason)")
case .multipartEncodingFailed(let reason):
print("Multipart encoding failed: /(error.localizedDescription)")
print("Failure Reason: /(reason)")
case .responseValidationFailed(let reason):
print("Response validation failed: /(error.localizedDescription)")
print("Failure Reason: /(reason)")
switch reason {
case .dataFileNil, .dataFileReadFailed:
print("Downloaded file could not be read")
case .missingContentType(let acceptableContentTypes):
print("Content Type Missing: /(acceptableContentTypes)")
case .unacceptableContentType(let acceptableContentTypes, let responseContentType):
print("Response content type: /(responseContentType) was unacceptable: /(acceptableContentTypes)")
case .unacceptableStatusCode(let code):
print("Response status code was unacceptable: /(code)")
statusCode = code
}
case .responseSerializationFailed(let reason):
print("Response serialization failed: /(error.localizedDescription)")
print("Failure Reason: /(reason)")
// statusCode = 3840 ???? maybe..
default:break
}
print("Underlying error: /(error.underlyingError)")
} else if let error = response.result.error as? URLError {
print("URLError occurred: /(error)")
} else {
print("Unknown error: /(response.result.error)")
}
print(statusCode) // the status code
}
(Alamofire 4 contiene un sistema de error completamente nuevo, mira here para más detalles)
Para usuarios de Swift 2.x con Alamofire> = 3.0
Alamofire.request(.GET, urlString)
.responseString { response in
print("Success: /(response.result.isSuccess)")
print("Response String: /(response.result.value)")
if let alamoError = response.result.error {
let alamoCode = alamoError.code
let statusCode = (response.response?.statusCode)!
} else { //no errors
let statusCode = (response.response?.statusCode)! //example : 200
}
}
Para usuarios de Swift 2.0 con Alamofire> 2.0
Alamofire.request(.GET, url)
.responseString { _, response, result in
if response?.statusCode == 200{
//Do something with result
}
}
Su error indica que la operación se está cancelando por algún motivo.
Necesitaría más detalles para entender por qué.
Pero creo que el problema más grande puede ser que, dado que su punto final
https://host.com/a/path
es falso, no hay una respuesta real del servidor para informar y, por lo tanto, está viendo
nil
.
Si golpea un punto final válido que sirve una respuesta adecuada, debería ver un valor no nulo para
res
(usando las técnicas que Sam menciona) en forma de un objeto
NSURLHTTPResponse
con propiedades como
statusCode
, etc.
Además, para ser claros, el
error
es de tipo
NSError
.
Le dice por qué falló la solicitud de red.
El código de estado de la falla en el lado del servidor es en realidad una parte de la respuesta.
Espero que ayude a responder su pregunta principal.
puede consultar el siguiente código para el controlador de código de estado por alamofire
let request = URLRequest(url: URL(string:"url string")!)
Alamofire.request(request).validate(statusCode: 200..<300).responseJSON { (response) in
switch response.result {
case .success(let data as [String:Any]):
completion(true,data)
case .failure(let err):
print(err.localizedDescription)
completion(false,err)
default:
completion(false,nil)
}
}
Si el código de estado no se valida, se ingresará la falla en la caja del interruptor
Alamofire
.request(.GET, "REQUEST_URL", parameters: parms, headers: headers)
.validate(statusCode: 200..<300)
.responseJSON{ response in
switch response.result{
case .Success:
if let JSON = response.result.value
{
}
case .Failure(let error):
}