Desserialización de JSON a Objetos Kotlin en APIs REST
Clase 13 de 20 • Curso de Patrones MVVM en Android
Resumen
La integración de datos de un API en una interfaz de usuario (UI) permite brindar a los usuarios la información que necesitan de forma clara y concisa. Es fundamental enviar y recibir datos entre una aplicación y un API, y transformarlos adecuadamente para su visualización.
¿Por qué es necesaria la deserialización de datos?
La deserialización consiste en transformar la respuesta recibida de un servicio REST, que generalmente está en formato JSON, a un lenguaje de programación que pueda entender nuestra aplicación. En este caso, hemos convertido JSON en objetos Kotlin. Este paso es crucial para renderizar la información correctamente en la UI, permitiéndonos trabajar con estructuras de datos conocidas por el lenguaje que usamos.
¿Cómo se incorpora la carga de imágenes en el proyecto?
Para mostrar imágenes de manera eficiente desde una API, es importante utilizar una librería adecuada. En el caso de este proyecto, hemos agregado la librería Coil Network OKHTTP
:
implementation("io.coil-kt:coil:1.3.2")
Este complemento nos permite cargar imágenes desde URLs proporcionadas por la API de forma rápida y sencilla.
¿Qué ajustes se realizaron durante la deserialización?
Durante el proceso de deserialización, tuvimos que considerar la nulabilidad de ciertos datos para evitar que la aplicación falle si faltan algunos valores esperados. Aquí se muestran algunos pasos clave realizados:
- Modificar modelos de datos y dominio para aceptar tipos nuleables.
- Implementar el operador Elvis (
?:
) para manejar valores nulos y asignarles un valor por defecto si es necesario.
val calculatedCalories = (it.nutriments.carbohydratesPer100g ?: 0) * 4
¿Cómo se crea un componente visual que gestione la interacción del usuario?
Para renderizar la información visualmente, es útil crear componentes de UI que faciliten la interacción del usuario. En este proyecto, creamos el componente truckableFoodItem
, que incluye:
- Un sistema de imágenes usando Coil.
- Información textual bien estructurada, con gestión de textos largos mediante elipsis.
- Una flecha de expansión animada que permite mostrar opciones adicionales interactuando con el ítem.
¿Cómo se gestiona el estado de búsqueda en la UI?
Para manejar el estado de búsqueda, se crearon clases selladas y estados que permiten gestionar eventos como cambios en la consulta (query) o en el foco del buscador:
fun onEvent(event: SearchEvent) {
when (event) {
is SearchEvent.OnQueryChange -> {
state = state.copy(query = event.query)
}
is SearchEvent.OnSearch -> {
executeSearch()
}
// Otros eventos...
}
}
¿Cómo se integra la búsqueda y la visualización de los resultados?
Al final, conectamos todos los componentes previamente mencionados para que la aplicación sea capaz de aceptar entradas del usuario, realizar búsquedas con esas entradas, y mostrar los resultados adecuadamente dentro de una lista utilizando LazyColumn
:
LazyColumn {
items(state.trackableFood) { food ->
TruckableFoodItem(
food = food,
onClick = { /* Acción al hacer clic sobre un ítem */ },
onAmountChange = { /* Acción para cambiar cantidad */ },
onTrack = { /* Acción de rastrear */ }
)
}
}
Es esencial validar qué campos de la API son obligatorios y opcionales, para que no se rompa la aplicación al consumir el servicio. Así, se garantiza una aplicación robusta y con la capacidad de adaptarse a los cambios en la estructura del API.
Con estos pasos, no solo hemos implementado una búsqueda eficiente que conecta con un API externo, sino que también nos aseguramos de que el usuario final reciba toda la información completa y organizada. ¡Esperamos que continúes experimentando y aprendiendo más!