要求の失敗(および理想的には成功も)の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ボディを取得することは可能ですか?
ありがとう!
ForSwift 3.x/Swift 4.0/Swift 5.0ユーザー(Alamofire> = 4.0/Alamofire > = 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にはまったく新しいエラーシステムが含まれています。詳細は こちら をご覧ください)
Swift 2.xユーザーの場合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
}
}
以下の引数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):
}
Alamofire.request(URL).responseJSON { response in let status = response.response?.statusCode print( "STATUS\(状態)") }
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
}
エラーは、何らかの理由で操作がキャンセルされていることを示しています。理由を理解するには、さらに詳細が必要です。しかし、より大きな問題は、エンドポイントhttps://Host.com/a/path
が偽物であるため、報告する実際のサーバー応答がないため、nil
が表示される可能性があると思います。
適切な応答を提供する有効なエンドポイントに到達すると、res
などのプロパティを持つNSURLHTTPResponse
オブジェクトの形式で、statusCode
の非nil値が表示されます(サムが言及した手法を使用)。
また、明確にするために、error
はNSError
型です。ネットワーク要求が失敗した理由がわかります。サーバー側の障害のステータスコードは、実際には応答の一部です。
あなたの主な質問に答えるのに役立つことを願っています。
またはパターンマッチングを使用する
if let error = response.result.error as? AFError {
if case .responseValidationFailed(.unacceptableStatusCode(let code)) = error {
print(code)
}
}
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)
}
}
ステータスコードが検証されない場合、スイッチケースでエラーが入力されます
Alamofire> 2.0のSwift 2.0ユーザーの場合
Alamofire.request(.GET, url)
.responseString { _, response, result in
if response?.statusCode == 200{
//Do something with result
}
}