es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Cómo refactorizar la conversión de resultados genéricos tipados a una estructura sólida en Combine

Tengo esta construcción fea de devolver un tipo genérico como modelo sólido, ¿alguien tiene ideas para refactorizarlo y hacerlo más declarativo?

“`
extension NetworkingService {

func login(email: String, password: String) -> AnyPublisher<usermodel, apierror=""> {
func convertToModel() -> AnyPublisher<><userresponse>, APIError> {
return request(with: AuthRequests.login(email: email, password: password)).eraseToAnyPublisher()
}
return convertToModel().map { UserModel(with: $0.data!) }.eraseToAnyPublisher()
}

func request<t>(with endpoint: Endpoint) -> AnyPublisher<t, apierror=""> where T : Decodable {
//… retornar cualquier publicador con Decodable
}

}
“`</t,></usermodel,>

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Una forma de refactorizar este código para que sea más declarativo y eliminar el uso de AnyPublisher y eraseToAnyPublisher sería usar flatMap en lugar de convertToModel, y compactMap en lugar de desempaquetar forzadamente (!) en el cierre map:

    extension NetworkingService {
    
        func login(email: String, password: String) -> AnyPublisher<usermodel, apierror=""> {
            request(with: AuthRequests.login(email: email, password: password))
                .flatMap { response -> AnyPublisher<usermodel, apierror=""> in
                    guard let data = response.data else {
                        return Fail(error: APIError.invalidData).eraseToAnyPublisher()
                    }
                    let userModel = UserModel(with: data)
                    return Just(userModel).setFailureType(to: APIError.self).eraseToAnyPublisher()
                }
                .eraseToAnyPublisher()
        }
    
        func request<t: decodable="">(with endpoint: Endpoint) -> AnyPublisher<><t>, APIError> {
            //... devolviendo cualquier publicador con Decodable
        }
    }
    

    Esto simplifica el código y lo hace más legible encadenando las llamadas flatMap y map en el pipeline. El flatMap toma el ResponseObject<userresponse> devuelto por request y utiliza la declaración guard para extraer de forma segura el campo de datos de la respuesta. Si los datos son nulos, devuelve un publicador Fail con un error APIError.invalidData. Si los datos no son nulos, crea una nueva instancia de UserModel y la envuelve en un publicador Just, que luego se convierte de nuevo en un AnyPublisher. El método setFailureType establece el tipo de error en APIError, que es el tipo de error utilizado por el publicador Fail.</usermodel,></usermodel,>

Comments are closed.