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
等属性。
此外,只是要清楚, error
是NSError
types。 它告诉你为什么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 \(状态)”) }