Swift Alamofire : HTTP 응답 상태 코드를 얻는 방법


106

요청 실패에 대한 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 본문을 검색 할 수 있습니까?

감사!


1
인증되지 않은 경우 의도적으로 -999를 받게됩니다. 그 이유나 해결 방법을 잘 모르겠습니다 ...이 문제를 해결 했습니까?
Guido Hendriks 16. 01.

답변:


187

들면 신속한 3.X / 스위프트 4.0 / 스위프트 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에는 완전히 새로운 오류 시스템이 포함되어 있습니다. 자세한 내용 은 여기 를 참조하십시오.)

들어 스위프트 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.result.error는 Alamofire 오류를 제공 할 수 있습니다. StatusCodeValidationFailed, FAILURE: Error Domain=com.alamofire.error Code=-6003. 당신이 실제로 GET HTTP 응답 오류 원한다면 그것은 사용자에게 더 나은입니다response.response?.statusCode
Kostiantyn 코발

@KostiantynKoval 나는 당신과 동의합니다, 당신은 적절한 설명을했습니다. 나는 명확성을 위해 내 대답을 업데이 트
알레산드로 Ornano에게

50

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
                 }

안녕하세요, statusCode 200이 실패할까요? 내 요청은 서버 측에서 제대로 처리하지만 응답은 실패에 해당되었다
perwyl

1
내가 200을 생각하지 않는다 @perwyl 것은 HTTP 오류입니다은 다음을 참조하십시오 stackoverflow.com/questions/27921537/...
wcochran

2
서버가 반환하는 경우 @perwyl 상태 코드 (200)는 성공을 나타내는 200 및 응답을 나타내는 오류 (예 : 일부 특성 = false를 issuccess라고도 함), 당신은 처리해야하는 프론트 엔드 코드
Parama Dharmika

16
    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):
    }

이 API의 모범 사례를 자극
CESCO

URW :) 요청에 대해 라우터를 구현해보십시오. ;)
Abo3atef

11

alamofire를 사용하여 상태 코드를 얻는 가장 좋은 방법입니다.

 Alamofire.request (URL) .responseJSON {
  응답

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

}

5

당신에 responseJSON완료, 당신의 유형이 응답 객체의 상태 코드를 얻을 수 있습니다 NSHTTPURLResponse?:

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
}

3

오류는 어떤 이유로 작업이 취소되고 있음을 나타냅니다. 이유를 이해하려면 더 자세한 정보가 필요합니다. 하지만 더 큰 문제는 엔드 포인트 https://host.com/a/path가 가짜이기 때문에보고 할 실제 서버 응답이 없기 때문에 nil.

적절한 응답을 제공하는 유효한 엔드 포인트에 도달하면 , 등과 같은 속성 res을 가진 NSURLHTTPResponse객체 의 형태로 (Sam이 언급 한 기술을 사용하여) nil이 아닌 값이 표시되어야합니다 statusCode.

또한 명확하게 말하면 error유형 NSError입니다. 네트워크 요청이 실패한 이유를 알려줍니다. 서버 측의 실패 상태 코드는 실제로 응답의 일부입니다.

주요 질문에 대한 답변이 도움이되기를 바랍니다.


잘 잡았습니다. 저는 하단의 질문 목록에 너무 집중했습니다.
Sam

1
실제로 코드 401 Unauthorized를 수신합니다. 의도적으로 잘못된 암호를 전송하여 사용자가 암호를 잘못 입력하는 것을 시뮬레이트하여 해당 사례를 포착하고 사용자 피드백을 제공 할 수 있기 때문입니다. 내가 사용하는 실제 URL은 아니지만 올바른 비밀번호를 보낼 때 성공하는 합법적 인 URL을 사용하고 있습니다. 내 원래 게시물의 콘솔 출력은 실제 URL을 눌렀을 때의 실제 출력이며 (URL이 가짜임을 제외하고) res객체가 nil인 것을 볼 수 있으므로이 답변은 도움이되지 않습니다.
GregT 2015 년

명확히 해주셔서 감사합니다. 음, 여기에서 의심되는 유일한 것은 -999 오류입니다.하지만 문서에 따르면 요청이 취소되고 있다는 내용이 있습니다 (응답을받는 것조차 문제가 될 것입니다). 인증과 관련이없는 다른 유형의 오류에 대한 응답 객체를 인쇄하려고 했습니까? 그냥 궁금해.
rainypixels

ahhhh error우리가 제공하는 범위를 벗어난 상태 코드로 응답을 언급하고 있다고 생각 했습니다 validate(). 감사!!!
Gerald

3

또는 패턴 매칭 사용

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

매력처럼 작동했습니다.
alasker

3

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

상태 코드가 유효하지 않으면 스위치 케이스에 실패로 입력됩니다.


1

Alamofire> 2.0을 사용하는 Swift 2.0 사용자

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

1

실제 오류 코드 번호를 얻는 방법을 알아야했습니다.

다른 사람으로부터 프로젝트를 물려 받았고 .catch이전에 Alamofire에 대해 설정 한 조항 에서 오류 코드 를 가져와야했습니다.

} .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의 답변을 따르십시오.

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)
})
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.