Search code examples
swiftcombine

How to convert AnyPublisher<DataResponse<T, Error>, Never> to AnyPublisher<T, Error>


DataResponse is the object of Alamofire. It returns Decodable object and Error in success itself in .

Requirement is to pass on received Decodable object and Error separately. Is it feasible to transform AnyPublisher<DataResponse<T, Error>, Never> to AnyPublisher<T, Error>.

Consider T as any data type object.

func fetchDataViaAlamofire(usingURl url: String) -> AnyPublisher<T, Error> {
        return AF.request(url,
                          method: .get)
        .validate()
        .publishDecodable(type: T.self)
        .map { response in
            
            // ?
            // Cannot convert value of type 'DataResponse<T?, AFError>' to closure result type 'T'
            response.map { value in
                return response.value
            }
            
            // ?
            // Any way to convert AFError to Error in AnyPublisher<T, Error>
        }
        .receive(on: DispatchQueue.main)
        .eraseToAnyPublisher()
        
    }

Solution

  • First of all you have to add the generic parameter T in the signature of the method.

    AF provides the operator .value() to convert the types. Additionally you have to map/cast AFError to Error

    func fetchDataViaAlamofire<T: Decodable>(usingURL url: String) -> AnyPublisher<T, Error> {
        return AF.request(url, method: .get)
            .validate()
            .publishDecodable(type: T.self)
            .value()
            .mapError{$0 as Error}
            .receive(on: DispatchQueue.main)
            .eraseToAnyPublisher()
    }