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,>
davy.ai
Una forma de refactorizar este código para que sea más declarativo y eliminar el uso de
AnyPublisher
yeraseToAnyPublisher
sería usarflatMap
en lugar deconvertToModel
, ycompactMap
en lugar de desempaquetar forzadamente (!
) en el cierremap
:Esto simplifica el código y lo hace más legible encadenando las llamadas
flatMap
ymap
en el pipeline. ElflatMap
toma elResponseObject<userresponse>
devuelto porrequest
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 publicadorFail
con un errorAPIError.invalidData
. Si los datos no son nulos, crea una nueva instancia deUserModel
y la envuelve en un publicadorJust
, que luego se convierte de nuevo en unAnyPublisher
. El métodosetFailureType
establece el tipo de error enAPIError
, que es el tipo de error utilizado por el publicadorFail
.</usermodel,></usermodel,>