4 años en Flutter: Así rediseñé mi app más exitosa con +100k descargas

Nia Cubilla
6 min readAug 14, 2023

--

Creo que con el tiempo el UI del app se ha vuelto más minimalista

Para los que ya conocen el app, habrán podido ver su evolución a lo largo del tiempo, pero en resumen hice este app de ideas de negocios con el objetivo de aprender a desarrollar apps en Flutter.

Si quieres ver más detalles puedes leer este artículo y este otro donde fui compartiendo lo que iba aprendiendo.

¿Y a qué viene todo esto?

Pues que hace un mes lancé la nueva versión 3.0.0 con muchos cambios, de hecho, decidí reescribir toda la lógica de negocio desde cero.

Empecemos.

Arquitectura enfocada en servicios

Estuve un tiempo investigando y analizando las mejores prácticas para la arquitectura del app ya que quería que fuese robusta y escalable, pero que al mismo tiempo mantuviese cierto nivel de sencillez al ser un proyecto mantenido por una sola persona, osea yo.

Desde hace algunas versiones atrás venía experimentando con una arquitectura enfocada en servicios para ciertas funciones y para la nueva versión decidí finalmente mover todo a este modelo.

Si no estás familiarizado, te dejo esta brillante presentación de Angelina Fabbro donde explica cómo estructuraron el app Splice, también puedes encontrar aquí los slides de la presentación.

Esquema general de la arquitectura basada en servicios

En resumen, esta propuesta busca encapsular todas las funciones del app que tienen un nivel de interacción con funciones del dispositivo o llamados a una fuente externa. Esto es independiente de la librería que se use y hace más fácil y organizado poder cambiar o actualizar las librerías

Algunos ejemplos de servicios son las notificaciones push, almacenamiento local, text to speech así como conexión a Firebase, Crashlytics, Admob, etc.

Cuando descubrí este video y vi el enfoque de esta arquitectura sentí que por fin había encontrado algo que se alineaba a lo que estaba buscando y a mi filosofía de trabajo.

Se habla mucho de la arquitectura CLEAN, pero es tan “clean”, que muchas veces se vuelve “dirty” al crear una estructura tan pero tan subdividida que he llegado a ver hasta 3 niveles de directorios o más para “organizar” un solo archivo.

En mi opinión muy personal, si el directorio no va a contener más de un solo archivo, no vale la pena que sea un directorio específico para esto, pero esto es a mi gusto muy personal y a mi aversión a tener que navegar entre tantos sub sub subdirectorios y archivos. Sí, sé que hay un buscador de archivos, pero pues es mi gusto y bueno, es la preferencia de cada quién.

Para la nueva versión decidí implementar más a fondo esta arquitectura enfocada en servicios en el proyecto y pasé a evaluar el gran dilema al trabajar con aplicaciones móviles…

…sí, adivinaste; el manejador de estados.

Manejo de estados

Había venido trabajando con Provider bastante bien, pero sentía que habían limitantes aunque no tenía muy claro exactamente qué.

Si, ya sé, esto es la consecuencia directa de pasar resolviendo cada nuevo reto del app con código de Stackoverflow y algún youtuber hindú (demos gracias por los youtubers hindús), pero pues de una u otra manera se aprende.

En fin, luego de leer varios artículos y ver algunos tutoriales en Youtube, me decidí a probar Riverpod.

Debes estar preguntándote por qué no me pasé a BLoC (Business Logic Component) y es que pasa exactamente lo mismo que con la arquitectura CLEAN; Crea demasiado código “boilerplate” y agrega una capa de complejidad que no me extrañaría si hiciese correr a cualquier novato en la dirección contraria apenas verla.

Si, sé que hay librerías y extensiones que ayudan a generar todo este código, pero precisamente algo que quiero evitar es no entender qué está haciendo mi código o depender de más librerías de las necesarias y que luego estas dejen de recibir soporte (Me ha pasado varias veces).

Noticia de última hora:
Lo mejor es lo que te funcione a ti.
Lo mejor es lo que tú entiendas, te sea fácil y puedas aplicar.

Base de datos local

Una vez zanjado el debate del manejador de estados, la siguiente etapa me llevó a evaluar si seguir usando Hive como base de datos local o migrar a otro proyecto.

Algo que no mencioné es que uno de los criterios que usé para filtrar las librerías a usar era que el proyecto estuviese activamente desarrollado, es decir, la última actualización no mayor a 3–6 meses.

Flutter tiene tantas actualizaciones, debido en gran parte a las actualizaciones de las tiendas de aplicaciones, que es muy fácil que una librería quede rezagada rápidamente.

Encontré que el mismo autor de Hive “abandonó” este proyecto para enfocarse en Isar, su nueva librería de base de datos con muchas mejoras y demás, pero…

Si, viene un gran “pero”.

A pesar de las mejoras, desarrollo constante y demás puntos a favor, me encontré que Isar al ser más enfocado en querys complejos, soporte jSon, etc, ya no tenía el mismo rendimiento que Hive.

Sumado a esto, se perdió la sencillez de guardar los datos de tipo clave-valor y es porque Isar persigue ser un motor de base de datos y no un “simple”, gestor de datos clave-valor.

Si has leído con atención hasta este punto, podrás adivinar cuál fue mi decisión…

Acertaste, me quedé con Hive.

Peticiones de red/API

Para la parte de peticiones al API me quedé con Dio que ya venía usando desde la primera versión, pero decidí cambiar dio_http_cache ya que esta librería tiene 2 años sin actualizarse. La reemplacé por dio_cache_interceptor junto con dio_cache_interceptor_hive_store y de paso agregué dio_smart_retry.

Sin embargo, estuve evaluando si usar http ya que incluye nativamente una librería para volver a procesar las consultas: package:http/retry.dart

Además cuenta con dio_http_cache para el manejo de caché, solo que esta librería tiene 2 años sin actualización, así que esto me terminó de decidir por Dio.

Diseño de interface UI

Finalmente para el diseño me decidí por cambiar ese menú aburrido con demasiadas opciones a una interfaz más limpia con navegación en la parte inferior usando BottomNavigationBar() y un IndexedStack().

Menú de navegación en la parte inferior

También agregué un buscador, esto era algo que quería hacer desde hace tiempo, pero ahora me fue más fácil crearlo gracias a Riverpod.

Además cambié el filtro de categorías por uno más bonito ya que antes los artículos se filtraban con un feo menú tipo “drop-down”.

También agregué un acceso directo tipo carrusel desde el home a los contenidos guardados en favoritos. Esto solo aparece cuando agregas el primer contenido a favoritos, dejando la interface inclusive más limpia cuando usas el app por primera vez.

También agregué una página de perfil donde se administran las preferencias de usuario como el idioma, modo nocturno y notificaciones.

Mantuve otras funcionalidades como el text to speech, barra de progreso de lectura y mantuve la pantalla de insignias donde mantengo la experiencia de gamification, pero separé el registro de contenidos leídos y días de racha en tabs usando TabBar() y un TabBarView(). Me parece que se ve más limpio así.

Y bueno esto es todo lo que cambié hasta ahora.

¿Cómo podriá mejorar el app? ¿Se te ocurre algo que pueda agregar o cambiar para incentivar el uso del mismo? Déjame saber en los comentarios.

Si te gustó esta publicación, házmelo saber en los comentarios. Siéntete libre de dar aplausos y compartirlo como quieras.

--

--

Nia Cubilla

Apasionada de la vida. Fan de StarWars, anime, comics, Marvel, Legofan. Panamá 🇵🇦 https://ideasdenegocios.app