Home > Back-end >  Alamofire 5 return AFError as Generic Error
Alamofire 5 return AFError as Generic Error

Time:10-13

I am trying to develop generic network layer which supports closure, async and combine features.

I want network layer not to depend on any library.

Protocol:

import Combine
import Foundation

protocol NetworkService {
    // Closure
    func get<ResponseModel>(endpoint: String,
                            response: ResponseModel.Type,
                            completion: @escaping (Result<ResponseModel, Error>) -> Void) where ResponseModel: Decodable

    // Async
    func get<ResponseModel>(endpoint: String,
                            response: ResponseModel.Type) async -> Result<ResponseModel, Error> where ResponseModel: Decodable

    // Combine
    func get<ResponseModel>(endpoint: String,
                            response: ResponseModel.Type) -> AnyPublisher<Result<ResponseModel, Error>, Never> where ResponseModel: Decodable
}

When implementing protocol in Alamofire, i get errors.

Implementation:

import Alamofire
import Combine
import Foundation

final class AlamofireService: NetworkService {
    let session: Session

    // Encoder and Decoder
    let encoder = JSONEncoder()
    let decoder = JSONDecoder()

    init() {
        session = Session()
    }

    // Closure
    func get<ResponseModel>(endpoint: String,
                            response: ResponseModel.Type,
                            completion: @escaping (Result<ResponseModel, Error>) -> Void) where ResponseModel: Decodable
    {
        session
            .request(endpoint, method: .get)
            .validate()
            .responseDecodable(of: response, decoder: decoder) {
                completion($0.result)
            }
    }

    // Async
    func get<ResponseModel>(endpoint: String,
                            response: ResponseModel.Type) async -> Result<ResponseModel, Error> where ResponseModel: Decodable
    {
        let result = await session
            .request(endpoint, method: .get)
            .validate()
            .serializingDecodable(response, decoder: decoder)
            .result

        return result
    }

    // Combine
    func get<ResponseModel>(endpoint: String,
                            response: ResponseModel.Type) -> AnyPublisher<Result<ResponseModel, Error>, Never> where ResponseModel: Decodable
    {
        let result = session
            .request(endpoint, method: .get)
            .validate()
            .publishDecodable(type: response, decoder: decoder)
            .result()

        return result
    }
}

Errors:

Closure: Cannot convert value of type 'Result<ResponseModel, AFError>' to expected argument type 'Result<ResponseModel, any Error>'

Async: Cannot convert return expression of type 'Result<ResponseModel, AFError>' to return type 'Result<ResponseModel, any Error>'

Combine: Cannot convert return expression of type 'AnyPublisher<Result<ResponseModel, AFError>, Never>' to return type 'AnyPublisher<Result<ResponseModel, any Error>, Never>'

My question is how can i convert AFError to Error?

CodePudding user response:

Yes, the compiler just doesn't convert it for you automatically. Easiest way to convert is to use mapError { $0 as Error }.

await session
    .request(endpoint, method: .get)
    .validate()
    .serializingDecodable(response, decoder: decoder)
    .result
    .mapError { $0 as Error }
  • Related