Nuestro equipo de desarrollo móvil utiliza SwiftUI desde 2022 para desarrollar Infomaniak Mail en iOS. Hoy en día, es uno de los mayores proyectos de código abierto escrito 100% en SwiftUI. El atractivo del nuevo framework de Apple es indudable, pero sigue siendo un reto para los desarrolladores. Muy pocas empresas se atreven a utilizarlo al 100%. Por un lado, está la juventud del framework con una documentación borrosa o incompleta. Por otro, es necesario cambiar profundamente las lógicas aprendidas. En este artículo, los desarrolladores de Infomaniak comparten sus experiencias sobre la adopción de SwiftUI para Infomaniak Mail.

¿Por qué elegir SwiftUI para lanzar nuestra app de correo dedicada?

Queríamos facilitar la rápida evolución de la aplicación y tener acceso a las últimas novedades. SwiftUI es la base de las próximas innovaciones en todas las plataformas de Apple: no solo en iOS, sino también en macOS y VisionOS.

Este nuevo framework trae varias ventajas para los desarrolladores:

  • Su sintaxis declarativa permite describir las interfaces de usuario de forma más concisa y legible.
  • Su sistema de previsualización permite ver inmediatamente los cambios sin necesidad de compilación.
  • La división de las vistas en componentes reutilizables optimiza la mantenibilidad de la aplicación.
  • La integración con Swift permite utilizar las últimas incorporaciones del lenguaje, como la API FormatStyle, directamente en las zonas de texto.
  • El apoyo a la internacionalización y accesibilidad facilita el uso de la app por parte de todos sin tener que escribir código explícito, a diferencia de UIKit.

Si hacemos balance, la forma histórica de trabajar con UIKit todavía coexiste muy bien con SwiftUI, pero ¿por cuánto tiempo? Como se puede ver a través de muchos ejemplos, Apple presenta su nuevo framework de una manera determinada. Las novedades de los sistemas operativos requieren SwiftUI para implementarse, como es el caso de los widgets o las Live Activities. Por lo tanto, el nuevo framework se convierte en un imprescindible para que funcionen las últimas características. También queríamos evitar que la aplicación dependiera de una tecnología que se quede obsoleta demasiado pronto.

Los desafíos de SwiftUI en comparación con UIKit

Si bien hoy en día nuestro equipo está formado en SwiftUI, ha habido errores, titubeos y retrasos, principalmente por las siguientes razones:

1. Mantener la compatibilidad para dispositivos antiguos

Para limitar la obsolescencia programada y los cambios demasiado frecuentes de dispositivo, es necesario conservarlos el mayor tiempo posible. Nos quedamos voluntariamente con SwiftUI 3 lanzado con iOS 15 en lugar de SwiftUI 5 lanzado con iOS 17 para que fuera compatible con los dispositivos de todos nuestros clientes que ejecutan iOS 15 (aproximadamente el 5% de nuestros usuarios).

Sin embargo, esta voluntad representa un reto para el equipo móvil de Infomaniak: el framework, lanzado en 2019 con iOS 13, todavía es joven y evoluciona muy rápidamente. Aunque Apple está solucionando rápidamente las deficiencias de SwiftUI a lo largo de los años, la compatibilidad con iOS 15 limita el uso de las nuevas API.

2. Gestión del cambio

El cambio a SwiftUI comenzó en 2022, cuando el desarrollo de un POC ya había comenzado con UIKit. En ese momento no teníamos experiencia con el nuevo framework con nuestras aplicaciones preexistentes. Algunos de nuestros desarrolladores que ya estaban experimentando por su cuenta con una vigilancia tecnológica activa tomaron la iniciativa en buenas prácticas y formaron a otros.

A pesar de que el entorno era familiar, tuvimos que superar cierta resistencia al cambio y aprender una nueva forma de hacer las cosas.

Tomamos la decisión de desarrollar todo usando SwiftUI. Cada nueva vista o componente usaba SwiftUI y las vistas desarrolladas previamente con UIKit fueron reemplazadas a medida que las maquetas cambiaban y requerían desarrollo.
Philippe Weidmann, Tech Lead iOS – Infomaniak

La gestión del cambio fue el primer gran desafío para un equipo entrenado y acostumbrado a UIKit, ya que la lógica de desarrollo es fundamentalmente diferente con SwiftUI:

Con el método histórico UIKit (el método imperativo), la disposición y el comportamiento de cada elemento de la interfaz se gestionan manualmente mediante restricciones muy detalladas. Es necesario definir cómo deben posicionarse y dimensionarse las vistas y los controles entre sí y en relación con sus contenedores. También es necesario establecer la lógica para responder a diferentes eventos, como la introducción de un campo y la actualización de los elementos en consecuencia.

Con el nuevo enfoque SwiftUI, basta con describir la vista que quieres obtener con los estados y las relaciones entre los elementos (el método declarativo). El framework gestiona automáticamente el diseño y las interacciones en función de los cambios en los datos de la aplicación (programación reactiva).

Al final, SwiftUI es más eficiente e intuitivo una vez que hemos logrado hacer nuestra la lógica.

El aprendizaje pasa por varias fases con una tendencia a conservar nuestros reflejos como:

  • Escribir desde SwiftUI a la manera UIKit (pensamos que sería bueno).
  • Preferir escribir en UIKit para resolver un problema rápidamente en lugar de abordarlo con SwiftUI, que a menudo requiere aprender a través de tutoriales.

Entonces la curva de aprendizaje se endereza. Con UIKit, tenemos el control de todos los detalles. Esto da una comprensión completa de lo que está sucediendo. Por el contrario, esta facilidad de SwiftUI oculta los mecanismos internos. Esto puede hacer que algunos errores visuales o problemas de rendimiento sean difíciles de detectar sin un conocimiento profundo del framework.

Para superarlo, nuestro equipo recurrió a la comunidad, a la investigación y a muchas pruebas. El empirismo nos ha permitido evaluar las direcciones a tomar y superar los obstáculos.

3. Fluidez y rendimiento

SwiftUI es un framework simple y rápido de usar, pero más complicado para crear interfaces eficientes y optimizadas. Las optimizaciones no están necesariamente bien documentadas por Apple.

En nuestro caso, la aplicación Infomaniak Mail debe comportarse del mismo modo para los usuarios que tienen 12 correos en su bandeja de entrada que para los que tienen 50.000. Lo mismo ocurre con los avatares de contactos, que deben aparecer sin problemas en todas las conversaciones, independientemente del número de participantes. No fue así.

Como explicamos más adelante, nos hemos dado cuenta de que hay cosas que no se deben hacer con este Framework. Sin embargo, hace falta que haya información.

4. Personalización de la aplicación: restricciones UI/UX

Infomaniak apuesta por su propia identidad visual coherente en todas las plataformas, Android e iOS, aunque se aleja de las convenciones de Apple.

SwiftUI es a veces resistente a la personalización de componentes y ofrece pocas opciones. Apple está empujando a los desarrolladores a utilizar el sistema de diseño de Apple, es decir, el look and feel que se encuentra en aplicaciones nativas como Mail o Recordatorios.

En varias ocasiones hemos tenido que crear nuestros propios componentes en lugar de usar los que están disponibles, y a veces hemos tenido que luchar contra el framework para lograr nuestros objetivos. Por ejemplo, utilizando mecanismos nativos, las aplicaciones muestran el título de las vistas (en este caso, el nombre de la carpeta Bandeja de entrada de la aplicación Mail) de forma centrada. La aplicación Infomaniak Mail debe utilizar su propia mecánica para mostrar el título a su manera:

Mostrar el título para Infomaniak Mail
Mostrar el título en una aplicación nativa (aquí Mail)

Para hacer que la redacción de correos sea más accesible, nuestra aplicación tiene un botón «Nuevo mensaje» llamado botón flotante. No existe en el sistema de diseño de iOS, sino más bien en las aplicaciones de Android. Tuvimos que desarrollarlo desde cero.

Este botón debería retirarse automáticamente para dejar espacio para que el usuario pueda ver su lista de correo cuando se desplace por ella. Es un reto técnico, ya que es necesario saber cuándo se desplaza el usuario por la lista, y SwiftUI no ofrece un mecanismo simple para hacerlo.

Botón flotante desplegado
Botón flotante retraído

La aplicación Infomaniak Mail también permite al usuario seleccionar correos mediante pulsación larga para actuar sobre varios mensajes. SwiftUI no ofrece esta mecánica de forma nativa, ya que se aleja de los estándares de Apple. Así que creamos todo nosotros mismos.

La personalización nos llevó a aprender a superar los escenarios previstos por Apple.

SwiftUI simplifica la creación de componentes y la iteración del diseño, pero la personalización sigue siendo difícil. Para los componentes, UIKit requiere más tiempo y es más farragoso, pero es mucho más fácil hacer lo que quieras para la personalización.
Philippe Weidmann, Tech Lead iOS – Infomaniak

Implementación de los principales componentes de la aplicación Infomaniak Mail con SwiftUI

Tres componentes principales de la aplicación Mail plantearon desafíos específicos de SwiftUI:

1. La lista de correos electrónicos: la parte que requiere más rendimiento

La lista de correos electrónicos es un punto central de la experiencia del usuario. Puede contener una gran cantidad de elementos, en varios modos de visualización (compacto, estándar, ancho). En la práctica, algunos usuarios mantienen todos sus correos electrónicos en una sola carpeta. Por lo tanto, debemos asegurarnos de que la navegación siempre sea fluida y eficiente, independientemente del número de correos que haya en la lista del usuario.

En su documentación, Apple sugiere que usar el componente «List» de SwiftUI debería ser simple: tomar cada elemento de la lista y mostrarlo. En teoría, el desarrollador no debería hacerse más preguntas.

Pero la realidad es más compleja. Cuando hay muchos elementos, las limitaciones de un smartphone pueden afectar el rendimiento. Siempre ha habido mecanismos integrados en iOS para mostrar listas largas sin afectar la fluidez. Se habla de reutilización de las celdas de una lista cuando el sistema sólo muestra los elementos visibles en la pantalla y va a reutilizar los elementos a medida que aparecen y desaparecen de la pantalla. SwiftUI oculta estos mecanismos a los desarrolladores y el propio framework asegura la reutilización de las celdas por razones de simplicidad.

La forma en que implementamos inicialmente nuestra lista no permitía a SwiftUI garantizar la reutilización adecuada de los elementos y calcular las diferencias cuando se realizaba un cambio en la lista. Concretamente, una lista de 50.000 correos electrónicos podía tardar más de un segundo en mostrarse en los dispositivos más antiguos, mientras que el resto de la interfaz se ralentizaba considerablemente. En la documentación del componente List no se explicaba el problema.

Los problemas de rendimiento son un tema recurrente con SwiftUI. La documentación para desarrolladores no mencionaba explícitamente el impacto en el rendimiento del uso de un controlador de Flow directamente dentro de una lista. Solo con los consejos de un breve vídeo (Demystify SwiftUI Performance) para la WWDC 2023 pudimos resolver nuestros problemas y mejorar significativamente nuestro rendimiento.

La documentación de Apple suele ser de buena calidad, pero recomendamos encarecidamente a los desarrolladores que sigan las sesiones de vídeo de la WWDC, que están repletas de información interesante y muy bien producidas. Todo está disponible de forma gratuita.

2. Redactar un mensaje

La parte de redacción de los mensajes consta de dos elementos principales:

  • La cabecera (que incluye los destinatarios y el asunto del correo)
  • La parte del cuerpo del mensaje (que es una vista web)

En la cabecera, la app Mail sugiere contactos con el nombre y el avatar. Cuando se selecciona y valida el contacto, su nombre se convierte en un componente llamado «chip» (botón pequeño) y se añade a la lista de destinatarios. Si es activado por el usuario, el chip muestra un cuadro de diálogo para eliminar el destinatario. Estos elementos no son típicamente previstos por SwiftUI y requieren un desarrollo personalizado.

En el cuerpo del mensaje, el usuario escribe su texto en una WebView. En otras palabras, escribe una página HTML sin darse cuenta. Desde el punto de vista de los desarrolladores, es necesario establecer un vínculo entre el contenido del mensaje tal como se muestra en la vista web y lo que finalmente será enviado al destinatario (el código nativo) por el servidor.

Escribir un nuevo mensaje es uno de los principales puntos de entrada de una aplicación de correo electrónico. Por lo tanto, es un punto de fricción potencialmente importante en la experiencia del usuario. Debido a que la visualización web móvil es un componente bastante pesado, nuestro equipo desarrollará un nuevo contenedor desde cero este año para mejorar el rendimiento.
Philippe Weidmann, Tech Lead iOS – Infomaniak

3. El menú lateral personalizado

Al igual que el botón flotante «Nuevo mensaje», el menú lateral deslizante que puedes desplegar pulsando el botón «hamburguesa» en la esquina superior izquierda no es un componente habitual en las plataformas de Apple. Es más bien una parte del «Material Design» de Google (Android). Se basa en una librería que permite optimizar y unificar el comportamiento de los elementos en todos los dispositivos. Pero dependiendo de cómo se diseña este menú deslizante con SwiftUI, puede ser muy poco eficiente. Tuvimos que desarrollarlo desde cero para conseguir el mismo look and feel.

Estas personalizaciones requieren un desarrollo específico en sí mismas, pero también generan más trabajo a la larga.

Como hemos hecho muchos componentes no previstos por SwiftUI, tenemos que notificar sistemáticamente estas adiciones a otras plataformas como iPadOS y posiblemente macOS. Adaptaciones que no tendríamos que haber hecho si hubiéramos seguido el framework de Apple al pie de la letra sin integrar nuestro propio sistema de diseño. La llegada de nuevas plataformas como VisionOS, por ejemplo, invita a la reflexión porque hace que sea más difícil adaptar nuestras personalizaciones.

El comportamiento natural de un menú lateral es abrirse u ocultarse desde el lado izquierdo de la pantalla siguiendo el pulgar del usuario. Debido a que no hay componente nativo en SwiftUI para este comportamiento, fue necesario implementar esta vista desde cero. Concretamente, esto implica superponer la vista del menú a la vista principal y desplazarla hacia la izquierda hasta que se vuelva invisible para ocultarla y a la inversa para mostrarla.

Inicialmente, el contenido del menú no estaba separado del contenedor del menú en sí, lo que planteaba graves problemas de rendimiento. De hecho, para cada variación del desplazamiento del menú (es decir, cada píxel de animación a la izquierda o a la derecha), se rediseñaba toda la vista. En un teléfono reciente, la ralentización no era visible, pero seguía consumiendo demasiada CPU según nuestros criterios. En un teléfono más antiguo, el usuario podía percibir una ralentización.

Por lo tanto, el primer paso fue identificar y medir el problema usando herramientas para asegurarnos de que los cambios realizados generaban beneficios reales.

A continuación, separamos la vista que contiene el menú (el contenedor) del contenido en sí. Esto permite que el framework SwiftUI rediseñe únicamente el contenedor sin tocar el contenido y, por lo tanto, aumente enormemente el rendimiento.

Balance de la transición de UIKit a SwiftUI

¿Y si tuvierais que hacerlo de nuevo? Seguiríamos eligiendo SwiftUI, pero avanzaríamos más gradualmente.

En retrospectiva, fue bastante atrevido e incluso doloroso pasar al 100% a SwiftUI de una vez.

Al principio estaba en contra de desarrollar la aplicación Infomaniak Mail completamente en SwiftUI. Fue una decisión difícil de tomar, pero hoy, si hubiera que hacerlo de nuevo, lo haríamos otra vez. Esto nos da una gran ventaja en el mantenimiento y desarrollo de la aplicación en el futuro.
Joris Bodin, Developer Team Leader – Móvil y Escritorio

Podemos ver los beneficios de SwiftUI al volver a trabajar con nuestras aplicaciones anteriores escritas en UIKit. Un ViewController UIKit que maneja una lista puede encontrarse rápidamente con varios cientos de líneas para escribir y mantener, mientras que unas pocas líneas de SwiftUI pueden ser suficientes.

Al desarrollar en SwiftUI, nos centramos principalmente en los datos a mostrar, mientras que UIKit requiere una gran cantidad de integración para lograr lo que queremos.

SwiftUI representa el futuro. El framework trae avances que cambian la vida, como la previsualización de la aplicación en directo en la interfaz de desarrollo. Históricamente, Apple ha demostrado que cuando ofrece una tecnología avanzada como SwiftUI, dura. Así que sabemos que nuestros esfuerzos probablemente no serán barridos en tres años, a diferencia de Google, que ofrece más novedades, pero las deja de lado más rápido. En este aspecto, el equivalente de SwiftUI en Android, JetPack Compose, es impulsado por una empresa distinta a Google, JetBrains. Creemos que esto le da a JetPack Compose más posibilidades de durar.

Aunque UIKit está lejos de ser superado y sigue siendo una buena opción en muchos casos, SwiftUI se está imponiendo poco a poco por sí mismo. Sus muchas ventajas facilitan el desarrollo y hacen que sea el futuro de las plataformas de Apple. Aunque dar el salto puede ser aterrador, no hay que dudar en lanzarse.
Valentin Perignon, desarrollador de iOS Infomaniak

Uno de los principales retos que tuvimos fue: «¿Cómo tener una identidad propia y seguir las pautas de Apple?» Hemos visto que lo que no está previsto en el framework conlleva una mayor carga de trabajo.

Nos gustaría aconsejar a los desarrolladores que duden que comiencen poco a poco. Una de las lecciones aprendidas de esta experiencia es que «si te resulta complicado, probablemente estás haciendo algo mal».

La documentación de SwiftUI no lo cubre todo y tuvimos que investigar para encontrar respuestas, especialmente sobre el rendimiento. Recomendamos ver los vídeos de las conferencias en línea (WWDC) de Apple que contienen información clave que puede desbloquear una situación.

Para nuestras otras aplicaciones, kDrive se desarrolló originalmente en iOS 12 con UIKit porque SwiftUI llegó sólo a partir de iOS 13 con los componentes que faltaban. Como no pudimos usar SwiftUI en ese momento, no tenemos la opción de reutilizar los componentes de kDrive en la app Infomaniak Mail. Estamos planeando migrar a SwiftUI poco a poco, a pedacitos, después de aprender de nuestra experiencia con la aplicación Mail.

Profesionalmente, dominar una tecnología de vanguardia como SwiftUI representa un valor importante en el mercado laboral. Sin embargo, recomendamos a los desarrolladores jóvenes que conozcan UIKit, ya que muchas compañías aún no han hecho el cambio. SwiftUI es una nueva tecnología «de moda» que pocos dominan actualmente, y estamos contentos de estar entre ellos.

Más información