code

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

codestyles 2020. 8. 26. 07:52
반응형

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 {
  response in

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

}

In your responseJSON completion, you can get the status code from the response object, which has a type of NSHTTPURLResponse?:

if let response = res {
    var statusCode = response.statusCode
}

This will work regardless of whether the status code is in the error range. For more information, take a look at the NSHTTPURLResponse documentation.

For your other question, you can use the responseString function to get the raw response body. You can add this in addition to responseJSON and both will be called.

.responseJson { (req, res, json, error) in
   // existing code
}
.responseString { (_, _, body, _) in
   // body is a String? containing the response body
}

Your error indicates that the operation is being cancelled for some reason. I'd need more details to understand why. But I think the bigger issue may be that since your endpoint https://host.com/a/path is bogus, there is no real server response to report, and hence you're seeing nil.

If you hit up a valid endpoint that serves up a proper response, you should see a non-nil value for res (using the techniques Sam mentions) in the form of a NSURLHTTPResponse object with properties like statusCode, etc.

Also, just to be clear, error is of type NSError. It tells you why the network request failed. The status code of the failure on the server side is actually a part of the response.

Hope that helps answer your main question.


Or use pattern matching

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

you may check the following code for status code handler by 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)
        }
    }

if status code is not validate it will be enter the failure in switch case


For Swift 2.0 users with Alamofire > 2.0

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

참고URL : https://stackoverflow.com/questions/29131253/swift-alamofire-how-to-get-the-http-response-status-code

반응형