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

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

감사!



답변

들면 신속한 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아래 인수가있는 완료 처리기 에서 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를 사용하여 상태 코드를 얻는 가장 좋은 방법입니다.

 Alamofire.request (URL) .responseJSON {
  응답

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

}


답변

당신에 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
}


답변

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

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

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

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


답변

또는 패턴 매칭 사용

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