我想检索请求失败的HTTP响应状态代码(例如400,401,403,503等)(理想情况下也是成功)。在此代码中,我正在使用HTTP Basic执行用户身份验证,并且希望能够在用户输错密码时向用户发送身份验证失败的消息。
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正文?
谢谢!
答案 0 :(得分:159)
Swift 3.x / Swift 4.0 / Swift 5.0 用户 Alamofire&gt; = 4.0 / Alamofire&gt; = 5.0
response.response?.statusCode
更详细的例子:
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包含一个全新的错误系统,详情请见here)
Swift 2.x 用户 Alamofire&gt; = 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
}
}
答案 1 :(得分:44)
在下面带参数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
}
答案 2 :(得分:15)
:m Data.Function
答案 3 :(得分:7)
Alamofire.request(URL).responseJSON { response in let status = response.response?.statusCode print("STATUS \(status)") }
答案 4 :(得分:5)
在responseJSON
完成后,您可以从响应对象中获取状态代码,其类型为NSHTTPURLResponse?
:
if let response = res {
var statusCode = response.statusCode
}
无论状态代码是否在错误范围内,这都将起作用。有关详细信息,请查看NSHTTPURLResponse documentation。
对于您的其他问题,您可以使用responseString
函数来获取原始响应正文。您可以在responseJSON
之外添加此内容,并且两者都会被调用。
.responseJson { (req, res, json, error) in
// existing code
}
.responseString { (_, _, body, _) in
// body is a String? containing the response body
}
答案 5 :(得分:3)
您的错误表示由于某种原因正在取消操作。我需要更多细节才能理解原因。但我认为更大的问题可能是因为您的端点https://host.com/a/path
是虚假的,所以没有真正的服务器响应报告,因此您看到nil
。
如果您点击了一个提供正确响应的有效端点,您应该以{{1}}对象的形式看到res
的非零值(使用Sam提到的技术) NSURLHTTPResponse
等属性
另外,为了清楚起见,statusCode
的类型为error
。它告诉您网络请求失败的原因。服务器端故障的状态代码实际上是响应的一部分。
希望这有助于回答您的主要问题。
答案 6 :(得分:2)
或使用模式匹配
if let error = response.result.error as? AFError {
if case .responseValidationFailed(.unacceptableStatusCode(let code)) = error {
print(code)
}
}
答案 7 :(得分:2)
您可以通过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)
}
}
如果状态代码未验证,则将在开关案例中输入失败
答案 8 :(得分:1)
对于使用Alamofire的Swift 2.0用户&gt; 2.0
Alamofire.request(.GET, url)
.responseString { _, response, result in
if response?.statusCode == 200{
//Do something with result
}
}
答案 9 :(得分:1)
我需要知道如何获取实际的错误代码编号。
我从其他人那里继承了一个项目,我不得不从他们先前为Alamofire设置的.catch
子句中获取错误代码:
} .catch { (error) in
guard let error = error as? AFError else { return }
guard let statusCode = error.responseCode else { return }
print("Alamofire statusCode num is: ", statusCode)
}
或者,如果您需要从response
值中获取它,请遵循@mbryzinski's answer
Alamofire ... { (response) in
guard let error = response.result.error as? AFError else { return }
guard let statusCode = error.responseCode else { return }
print("Alamofire statusCode num is: ", statusCode)
})
答案 10 :(得分:1)
对于具有 Alamofire> = 5.0 的 Swift 3.x / Swift 4.0 / Swift 5.0 用户
>使用请求修饰符来增加和减少超时间隔。
Alamofire的请求创建方法提供了最通用的自定义参数,但有时这些还不够。创建请求时,可以使用RequestModifier闭包来修改从传递的值创建的URLRequest。例如,要将 URLRequest的 timeoutInterval 设置为120秒,请在闭包中修改请求。
var manager = Session.default
manager.request(urlString, method: method, parameters: dict, headers: headers, requestModifier: { $0.timeoutInterval = 120 }).validate().responseJSON { response in
OR
RequestModifiers也可以使用结尾闭包语法。
var manager = Session.default
manager.request("https://httpbin.org/get") { urlRequest in
urlRequest.timeoutInterval = 60
urlRequest.allowsConstrainedNetworkAccess = false
}
.response(...)