J'aimerais récupérer le code d'état de la réponse HTTP (par exemple 400, 401, 403, 503, etc.) pour les demandes non satisfaites (et idéalement pour les succès également). Dans ce code, j'effectue une authentification d'utilisateur avec HTTP Basic et souhaite pouvoir informer l'utilisateur que l'authentification a échoué lorsque l'utilisateur a mal entré son mot de passe.
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")
}
Malheureusement, l'erreur générée ne semble pas indiquer qu'un code d'état HTTP 409 a effectivement été reçu:
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
De plus, il serait bien de récupérer le corps HTTP lorsqu'une erreur se produit car mon côté serveur y mettra une description textuelle de l'erreur.
Questions
Est-il possible de récupérer le code de statut sur une réponse non 2xx?
Est-il possible de récupérer le code de statut spécifique après une réponse 2xx?
Est-il possible de récupérer le corps HTTP sur une réponse non 2xx?
Merci!
Pour Swift 3.x / Swift 4.0 / Swift 5.0 utilisateurs avec Alamofire> = 4.0 / Alamofire > = 5.0
response.response?.statusCode
Exemple plus détaillé:
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 contient un tout nouveau système d'erreur, regardez ici pour plus de détails)
Pour Swift 2.x utilisateurs avec 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
}
}
Dans le gestionnaire d'achèvement avec l'argument response
ci-dessous, le code de statut http se trouve dans 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
}
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):
}
Alamofire.request (URL) .responseJSON { Réponse in Let status = response.response? .StatusCode Print ("STATUS\(statut)") }
Dans votre complétion responseJSON
, vous pouvez obtenir le code de statut de l'objet de réponse, qui a le type NSHTTPURLResponse?
:
if let response = res {
var statusCode = response.statusCode
}
Cela fonctionnera que le code d'état soit dans la plage d'erreur ou non. Pour plus d'informations, consultez le documentation NSHTTPURLResponse .
Pour votre autre question, vous pouvez utiliser la fonction responseString
pour obtenir le corps de réponse brut. Vous pouvez ajouter ceci en plus de responseJSON
et les deux seront appelés.
.responseJson { (req, res, json, error) in
// existing code
}
.responseString { (_, _, body, _) in
// body is a String? containing the response body
}
Votre erreur indique que l'opération est annulée pour une raison quelconque. J'aurais besoin de plus de détails pour comprendre pourquoi. Mais je pense que le plus gros problème est peut-être que, puisque votre terminal https://Host.com/a/path
est faux, il n’ya pas de réponse réelle du serveur à signaler, et vous voyez donc nil
.
Si vous trouvez un noeud final valide qui fournit une réponse correcte, vous devriez voir une valeur non nulle pour res
(à l'aide des techniques décrites par Sam) sous la forme d'un objet NSURLHTTPResponse
avec des propriétés telles que statusCode
, etc.
De plus, juste pour être clair, error
est de type NSError
. Il vous explique pourquoi la requête réseau a échoué. Le code d'état de la panne côté serveur fait en réalité partie de la réponse.
J'espère que cela aide à répondre à votre question principale.
Ou utilisez la correspondance de modèle
if let error = response.result.error as? AFError {
if case .responseValidationFailed(.unacceptableStatusCode(let code)) = error {
print(code)
}
}
vous pouvez vérifier le code suivant pour le gestionnaire de code d'état par 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 le code d’état n’est pas valide, il sera saisi de l’échec en cas de commutation
Pour Swift 2.0 utilisateurs d'Alamofire> 2.0
Alamofire.request(.GET, url)
.responseString { _, response, result in
if response?.statusCode == 200{
//Do something with result
}
}