Swift Alamofire: how to get HTTP response status code

I would like to receive an HTTP response status code (e.g. 400, 401, 403, 503, etc.) for request failures (and ideally for success). In this code, I authenticate the user using HTTP Basic and want to be able to tell the user that the authentication failed when the user mistakenly uses his password.

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") } 

Unfortunately, the error received does not indicate that an HTTP 409 status code was actually received:

 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 

In addition, it would be nice to get the HTTP body when an error occurs, because my server side will post a text description of the error there.

Questions
Is it possible to get a status code with a response not 2xx?

Is it possible to get a specific status code with a 2xx response?
Is it possible to get an HTTP body with a non-2xx response?

Thank!

+93
swift alamofire
Mar 18 '15 at 19:39
source share
9 answers

For Swift 3.x / Swift 4.0 / Swift 5.0 users with Alamofire> = 4.0 / Alamofire> = 5.0




 response.response?.statusCode 



More detailed example:

 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 contains a completely new error system, see details here )

For Swift 2.x users with 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 } } 
+154
Oct 13 '15 at 12:37
source

In the completion handler with the response argument below, I find the http status code in 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 } 
+44
Mar 14 '16 at 23:42 on
source
  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): } 
+15
Feb 19 '16 at 9:53 on
source

The best way to get the status code is with alamofire.

  Alamofire.request (URL) .responseJSON {
   response in

   let status = response.response? .statusCode
   print ("STATUS \ (status)")

 }
+7
Jul 01 '17 at 4:36 on
source

At the end of responseJSON can you get the status code from the response object, which is of type NSHTTPURLResponse? :

 if let response = res { var statusCode = response.statusCode } 

This will work regardless of whether the status code is in the error range. See the NSHTTPURLResponse documentation for more information.

For your other question, you can use the responseString function to get the body of the raw response. You can add this in addition to responseJSON , and both will be called.

 .responseJson { (req, res, json, error) in // existing code } .responseString { (_, _, body, _) in // body is a String? containing the response body } 
+4
Mar 18 '15 at 20:04
source

Your error indicates that the operation is canceled for any reason. I need more details to understand why. But I think the big problem could be that since your endpoint https://host.com/a/path is fictitious, there is no real server response to the report, and therefore you see nil .

If you have typed a valid endpoint that answers the correct answer, you should see the non-nil value for res (using Sam's methods) in the form of an NSURLHTTPResponse object with properties like statusCode , etc.

Also, to be clear, error is of type NSError . It tells you why the network request failed. The server-side failure status code is actually part of the response.

Hope that helps answer your main question.

+3
Mar 18 '15 at 20:47
source

Or use pattern matching

 if let error = response.result.error as? AFError { if case .responseValidationFailed(.unacceptableStatusCode(let code)) = error { print(code) } } 
+2
Mar 17 '17 at 16:03
source

you can check the following code for the status code handler with 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) } } 

if the status code is not checked, it will enter a failure in the case of a switch

+2
Dec 18 '17 at 9:50
source

For Swift 2.0 users with Alamofire> 2.0

 Alamofire.request(.GET, url) .responseString { _, response, result in if response?.statusCode == 200{ //Do something with result } } 
+1
Sep 17 '15 at 10:50
source



All Articles