приведение ответа сервера в AFError

Я пытаюсь добиться того, чтобы у меня был requestна сервер и обработайте ошибку через AFError. Однако иногда, когда ответ сервера равен 4xx, появляется собственное сообщение с этим ответом, которое я хочу показать пользователю, но не знаю, как его реализовать.

Это мое NetworkManager

          static let shared:NetworkManager = {
        return NetworkManager()
    }()
    typealias completionHandler = ((Result<Data, AFError>) ->Void)

    func handleAFrequest(request: DataRequest,completion: @escaping completionHandler) {
        
        request.validate(statusCode: 200..<300)
        request.responseJSON { (response) in
            
            switch response.result {
            case .success(_):
                
                if let data = response.data {
                    completion(.success(data))
                }
                
            case .failure(let error):
                print(error.localizedDescription)
                switch error {
                case .invalidURL(let url):
                    print("Invalid URL: \(url) - \(error.localizedDescription)")
                    completion(.failure(.invalidURL(url: URL)))
                
               case .responseValidationFailed(let reason):
                    print("Response validation failed: \(error.localizedDescription); Reason:\(reason)")
                    completion(.failure(.responseValidationFailed(reason: reason)))
                    

Я хочу иметь возможность отправлять ответ сервера в дополнение к ошибке и показывать Messageответа пользователю. Пример ответа сервера при StatusCode 4xx:

      {
   "data":
          "code":401;
          "Message":"Phone Invalid"
}

2 ответа

Это решение, которое работает для меня.

Все, что вам нужно сделать, это создать собственный тип ошибки:

      struct APIError: Error, Decodable {

    let status: Int?
    let message: String?
    let key: String?

}

Затем вызовите Alamofire, который вернет AFDataResponse , который вы можете разобрать:

       func performRequest<T: Decodable>(route: APIRouter, completion: @escaping (APIResponse<T>) -> Void) {
     let decoder = JSONDecoder()
     decoder.keyDecodingStrategy = .convertFromSnakeCase
     AF.request(route)
       .validate()
       .responseDecodable(decoder: decoder, emptyResponseCodes: [200, 201]) { (response: AFDataResponse<T>) in
           self.parseResponse(response: response, completion: completion)
       }
}

Разбор делается так:

      private func parseResponse<T: Decodable>(response: AFDataResponse<T>, completion: @escaping (APIResponse<T>) -> Void) {
        switch response.result {
        case .success(let data):
            completion(APIResponse<T>.success(data))
        case .failure(let error):    
            if let data = response.data,
            // THIS IS WHERE YOU CAST AFError TO YOUR CUSTOM APIError
               let apiError = try? JSONDecoder().decode(APIError.self, from: data) {
                completion(APIResponse.failure(apiError))
            } else {
                completion(APIResponse.failure(error))
            }
        }
    }

Надеюсь это поможет!

Я разбирал ошибки api во многих своих проектах. Я считаю, что есть лучшая альтернатива для обработки показа или ошибок, если таковые имеются, для пользователя. Пожалуйста, посмотрите мой код, в нем, если есть ошибка, я показываю ее в тосте. Отображение тоста - это не главное, но вы можете видеть, как я справляюсь с ошибкой в ​​моем коде, и это никогда не подводило. Измените параметры в соответствии с вашим вызовом API

      func postMethod(mylist: [String:Any]) {
    print(K.APIUrl)
    print(K.port)
    AF.request("\(K.urlFromUrlField!):\(K.configPort)/snhttp-01?", method: .put, parameters: mylist)
        .authenticate(username: username, password: password)
        .response { response in
            switch response.result {
            case .success:
                print("\nValidation Successful from put method")
                print(response.result)
                print(response.value as Any)
                
                //get xml code and error msg if any
                
                if let response = response.data{
                    
                    let xml = XML.parse(response)
                    print(xml)
                    print("\nThis is the data sent to the server: \(mylist["data"] ?? "No data in data key of the parameter")" )
                    
                    let code = xml.Response.Code.text ?? "No code value in response"
                    let responseMessage = xml.Response.Message.text ?? "No message returned from server"
                    
                    print("\nCode value from server: \(code)")
                    print("\nResponse message from server: \(responseMessage)")
                }
                
                else{
                    print("\nSuccess block: Request Successfully sent, BUT there was nothing from the server to unwrap! / nothing sent back from the server\nThis is the data sent to the server: \(mylist["data"] ?? "No data in data key of the parameter")")
                }
                
                
            case let .failure(error):
                
                if let response = response.data {
                    let xml = XML.parse(response)
                    
                    let code = xml.Response.Code.text ?? "\nNo code value in response"
                    let responseMessage = xml.Response.Message.text ?? "No message returned from server"
                    
                    print("\nCode value from server: \(code)")
                    print("\nResponse message from server: \(responseMessage)")
                    print(error)
                    
                }
                
                else    {
                    print("\nFailure Block: A connection to the server could not be established")
                    
                }
                
            }}
    
    }

Этот код анализирует xml из api. Однако вы можете отказаться от этого и просто сосредоточиться на том, как я обрабатываю ответ и, следовательно, на ошибку.

Другие вопросы по тегам