Swift Alamofire:如何获取HTTP响应状态码

我想检索请求失败的HTTP响应状态码(例如400,401,403,503等)(理想情况下也是成功的)。 在此代码中,我正在使用HTTP Basic执行用户身份validation,并希望能够在用户键入密码时向用户发送身份validation失败的信息。

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

不幸的是,所产生的错误似乎并不表示实际上收到了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 

此外,当发生错误时,检索HTTP正文会很好,因为我的服务器端会在那里放置错误的文本描述。

问题
是否有可能检索非2xx响应状态码?
是否有可能检索2xx响应的特定状态码?
是否有可能在非2xx响应中检索HTTP正文?

谢谢!

对于Alamofire> = 4.0的 Swift 3.x / Swift 4.0用户

 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.. } 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包含一个全新的错误系统, 在这里查看细节)

对于Alamofire> = 3.0的 Swift 2.x用户

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

在下面的参数response完成处理程序中,我发现http状态码是在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): } 

在您的responseJSON完成中,您可以从响应对象获取状态码,该对象具有NSHTTPURLResponse?typesNSHTTPURLResponse?

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

无论状态码是否在错误范围内,这都将起作用。 有关更多信息,请查看NSHTTPURLResponse文档 。

对于您的其他问题,您可以使用responseString函数来获取原始响应主体。 你可以添加这个除了responseJSON ,这两个都会被调用。

 .responseJson { (req, res, json, error) in // existing code } .responseString { (_, _, body, _) in // body is a String? containing the response body } 

您的错误表示操作因某种原因被取消。 我需要更多的细节来理解为什么。 但我认为更大的问题可能是,因为你的端点https://host.com/a/path是虚假的,没有真正的服务器响应报告,因此你看到nil

如果你创build了一个有效的端点来提供正确的响应,你应该看到一个非零值的res (使用Sam提到的技术),以NSURLHTTPResponse对象的forms,例如statusCode等属性。

此外,只是要清楚, errorNSErrortypes。 它告诉你为什么networking请求失败。 服务器端失败的状态码实际上是响应的一部分。

希望有助于回答你的主要问题。

对于Alamofire> 2.0的Swift 2.0用户

 Alamofire.request(.GET, url) .responseString { _, response, result in if response?.statusCode == 200{ //Do something with result } } 

或者使用模式匹配

 if let error = response.result.error as? AFError { if case .responseValidationFailed(.unacceptableStatusCode(let code)) = error { print(code) } } 

使用alamofire获取状态码的最佳方法。

  Alamofire.request(URL).responseJSON {
  回应

  让status = response.response?.statusCode
  打印(“STATUS \(状态)”)

 }