Implementación de la interfaz de usuario en iOS: mejor, más rápido y escala



Hace unos meses me encontré con una serie documental muy interesante en Netflix llamada Abstract , que básicamente explora la producción de diseñadores profesionales de diferentes sectores como arquitectura, diseño gráfico, moda, ... en sus lugares de trabajo.

Fue fácil detectar algunas similitudes en el trabajo de diseñadores de otros campos con el de un desarrollador de iOS que implementa interfaces de usuario. Por ejemplo, cuando un diseñador está creando algo que es lo suficientemente grande como para dividirse en partes más pequeñas, usar una estrategia como ' Divide y vencerás' es clave para poder enfocarte en partes más pequeñas que se ensamblarán en etapas posteriores del proceso .

Desglosar un diseño completo en subunidades más pequeñas nos permite pensar en cada problema de forma aislada, eliminando cualquier dependencia entre los componentes. Pero la imagen completa también debe estar presente durante todo el proceso, de lo contrario puede haber problemas cuando llegue el momento de volver a unir todo.

Por otro lado, mientras miraba Resumen , noté que en el proceso de diseño de objetos como zapatos, pancartas o edificios, el diseño final permanece fijo durante la vida útil del producto. El diseño de un zapato Nike no cambiará después de su lanzamiento y no habrá actualizaciones una vez que esté en el estante de la tienda. A veces, un diseño permanece sin cambios incluso 20 años después, y el producto sigue siendo sólido.


Nike Air Max '97 - Empire State Building (Nueva York)

Muchos desarrolladores de iOS pasan mucho tiempo creando interfaces, definiendo interacciones y puliendo detalles de la IU como parte del proceso de creación de aplicaciones grandes y complicadas. Es necesario tener en cuenta el panorama general de la aplicación en su conjunto, por supuesto, pero es igualmente importante pensar en cómo mantener todos los componentes más pequeños separados y distintos, ya que estos componentes pequeños a menudo se pueden reutilizar más tarde al construir Otros elementos de la aplicación.


En el equipo de iOS en Badoo, tenemos lanzamientos semanales, que incluyen muchas características nuevas, mejoras y otros cambios que afectan la interfaz de usuario. Nuestro objetivo siempre es avanzar rápidamente y lanzar funciones de la más alta calidad posible, pero hace un año identificamos algunos problemas en nuestro proceso de desarrollo de interfaz de usuario y se nos ocurrió un plan para solucionarlo.

Descripción del problema


Trataré de definir el problema en una sola oración:
El equipo de iOS no tenía un proceso de desarrollo de interfaz de usuario claro.
¿Qué significaba esto en la práctica? Significaba que desarrollar cualquier nueva característica con cambios en la interfaz de usuario en la aplicación iOS podría generar todo tipo de problemas. Estos son los problemas más comunes que enfrentamos a diario:

  • La comunicación con los diseñadores no fue clara ni efectiva. Hubo poca transparencia con los diseñadores en torno a los componentes de UI existentes que habíamos implementado en las aplicaciones. Esto los obligó a crear nuevos componentes que se parecen mucho a los existentes.
  • No hubo patrones generalmente aceptados para la implementación de componentes de la interfaz de usuario. Cada desarrollador estaba implementando componentes de diferentes maneras y muchos de ellos no encajaban bien.
  • La duplicación de código estaba generando problemas significativos de arquitectura, agregando complejidad ciclomática, entre otros problemas.
  • Siempre fue muy difícil aplicar modificaciones en toda la aplicación para el mismo componente.
  • Hubo un mayor riesgo de introducir regresión en los componentes existentes a menos que sus modificaciones no estuvieran cubiertas por las pruebas.

No habría varita mágica para resolver estos problemas porque se trata del proceso. Cambiar la forma en que se hacen las cosas requiere alineación entre los diferentes equipos y convencer a las personas afectadas por el proceso sobre los beneficios de una nueva forma de hacer las cosas.

'Divide y vencerás' puede ser un enfoque útil aquí, comenzando con pequeños problemas, aislando cada problema y luego comenzando a construir una solución global paso a paso. ¡En este artículo explicaré cómo lo logramos!

Marcos de interfaz de usuario


Abordamos el problema comenzando desde la fundación. El primer problema a tratar fue la duplicación de código, necesitábamos unificar nuestros componentes y ponerlos a todos en un solo lugar.

Nuestra solución fue construir un par de marcos, que llamamos BadooUIKit. La idea era que esto contendría todos los componentes de la interfaz de usuario, similar a lo que Apple hace con UIKit. Contiene clases que representan las interfaces de usuario de una aplicación específica (hay algunas otras aplicaciones en nuestra empresa, pero este UIKit específico contiene solo componentes de interfaz de usuario que son específicos de la aplicación Badoo).

Cada aplicación tiene una paleta de colores, fuentes, márgenes, etc. diferentes, por lo que es útil tener un marco específico de la aplicación para agregar también hojas de estilo para la aplicación dentro del marco.



¿Qué sucede con los componentes de la interfaz de usuario que se pueden compartir y reutilizar en diferentes aplicaciones?

Para esto, creamos otro marco llamado Platform_UIKit. Este marco tiene todos los componentes genéricos de la interfaz de usuario que se pueden usar en diferentes aplicaciones.

¿Migramos inmediatamente toda la interfaz de usuario al nuevo marco?

No, eso habría sido una tarea enorme. En su lugar, decidimos construir cada nueva pieza de IU dentro del nuevo marco y solo intentamos mover los componentes existentes cuando afectaba nuestra tarea actual. En algunos casos, un componente podría tener muchas dependencias y, por lo tanto, sería difícil pasar de la aplicación principal al marco. En esos casos, generalmente optamos por realizar la tarea de migración por separado. Como parte del plan inicial, priorizamos elementos básicos como fuentes, colores, botones, etc.

Más tarde, una vez que se construyó la base, también migramos toda la interfaz de usuario para nuestro chat a un marco de interfaz de usuario. Lo hicimos en algún momento después de tener la infraestructura en funcionamiento y ayudó a tener un proceso de migración más fluido.

Nota al margen:
Si tiene curiosidad sobre el proceso de creación de uno de esos componentes, consulte este excelente artículo de mi colega Valerii Chevtaev

Un requisito muy importante para estos marcos es que no deben depender de otros marcos o clases que no sean estrictamente código de interfaz de usuario. Por ejemplo, nunca importamos modelos de la aplicación principal, clases relacionadas con la capa de red, reporteros de estadísticas, etc.

Al aislar la interfaz de usuario de otras dependencias, hacemos que los componentes sean lo más reutilizables posible:



Está bien que BadooUIKit importe desde Platform_UIKit, pero no al revés, por una simple razón, si Platform_UIKit depende de BadooUIKit ya no será independiente de la aplicación.



En Badoo, agregar esos marcos a nuestro proyecto no fue muy difícil y realmente no requiere mucho mantenimiento. Cada proyecto es diferente y encontrar la forma adecuada de construir una estructura no siempre es sencillo, pero es beneficioso tanto a corto como a largo plazo.

Estos son algunos de los beneficios de usar UIKit:

  • Tener los componentes de la interfaz de usuario en un solo lugar los hace más fáciles de encontrar y mantiene el proyecto mejor organizado, en lugar de tenerlos diseminados por toda la estructura del proyecto.
  • Liberar clases de dependencias internas ayuda a disminuir el tiempo de compilación en todo el proyecto.
  • La eliminación de dependencias no relacionadas con el código de la interfaz de usuario hace que los componentes sean más fáciles de reutilizar y reduce el tiempo de compilación.
  • Actualización de un componente en Badoo Si la aplicación se basa en componentes de BadooUIKit, es muy fácil aplicar los cambios en toda la aplicación.
  • Los componentes aislados son mucho más fáciles de probar.
  • Tener un marco separado lo hace reutilizable en otras aplicaciones si es necesario. Por ejemplo, crear una aplicación que enumere y presente todos los componentes en este marco.

La aplicación de la galería




BadooUIKit resolvió muchos de nuestros problemas, pero sabíamos que aún podíamos ir más allá, había algunas mejoras que se podían hacer en el proceso.

¿Cómo ver todos los componentes de la interfaz de usuario de forma aislada? ¿Podríamos idear una forma de encontrar componentes de la interfaz de usuario y ver cómo se verían con diferentes colores de código? ¿Podríamos hacerlos fácilmente comprobables? ¿Hubo alguna forma de que los diseñadores pudieran tener un catálogo de todos los componentes de UI existentes que ya estábamos implementando en iOS?

Como ya teníamos BadooUIKit como un marco de interfaz de usuario aislado, decidimos crear una aplicación independiente simple para uso interno. Presentamos la Galería Badoo.

El propósito de Badoo Gallery es servir como herramienta para que los desarrolladores, diseñadores e incluso el equipo de producto presenten los componentes de la interfaz de usuario de una manera amigable. En esta aplicación implementamos muchas características diferentes que facilitan la interacción con los componentes de la interfaz de usuario.

Como esta aplicación es una herramienta interna y no está destinada a su lanzamiento en la App Store, es posible agregar cualquier característica o herramienta que consideremos necesaria. En nuestro caso, identificamos las siguientes características como particularmente útiles:

  • Búsqueda de componentes
  • Nombre del componente ordenar
  • Marcar como favorito
  • Selector de estilos múltiples: para ver cómo se vería nuestro componente con diferentes hojas de estilo
  • Flex
  • Un visor de cuadros por segundo



Cada componente puede tener muchos estados diferentes dependiendo de la entrada del usuario o de la lógica intrínseca de la aplicación. Por ejemplo, un simple UIButton define varios estados: predeterminado, resaltado, enfocado, seleccionado y deshabilitado.

Curioso? Consulta aquí para más información.

También queríamos tener la capacidad de presentar todas las combinaciones en nuestra galería. Hacemos esto dentro de cada pantalla específica para cualquier componente. Por supuesto, nuestras propias versiones de botón pueden tener diferentes estados del botón UIKit de Apple.



Este es un resumen de los principales beneficios de la Galería Badoo:

  • Enumera todos los componentes de la interfaz de usuario que hemos implementado en iOS
  • Fácil búsqueda y búsqueda de componentes de UI. Ahora todos en nuestro equipo o equipo de productos pueden ver todas las opciones posibles de un componente de la interfaz de usuario y encontrar nuevos usos posibles para ellos.
  • Poder encontrar fácilmente componentes que ya existen hace que sea mucho más fácil convencer a un diseñador para que los reutilice
  • El tiempo de compilación de un proyecto muy pequeño como esta galería es muy corto. La velocidad de desarrollo de toda la función se puede acortar implementando la interfaz de usuario en esta aplicación ligera
  • La función de favoritos nos ayuda a encontrar los componentes que estamos implementando en este momento.
  • Agregar herramientas externas como FPS, multimarca y flex ayuda a comprender, mejorar y medir la calidad de los componentes de la interfaz de usuario que tenemos en el catálogo
  • Todos estos componentes están ahora en un marco separado y se presentan de forma aislada. ¡Esto los hace fácilmente comprobables!

Sobre las pruebas


La mayoría de los problemas iniciales enumerados en el artículo se han resuelto introduciendo el nuevo conjunto de herramientas:



Pero todavía había algunos problemas que podrían mejorarse, otras preguntas que debían responderse: al realizar cambios, ¿cómo podemos asegurarnos de que la IU se verá como esperábamos después de algunos cambios? ¿Cómo podemos evitar que otras partes de la aplicación u otros componentes se vean afectados negativamente cuando se modifican los "subcomponentes"?

Una buena manera de encontrar respuestas a todas esas preguntas es agregando pruebas a los componentes de la interfaz de usuario. Ya existe mucha documentación sobre cómo implementar pruebas de IU en iOS. También hay muchas herramientas diferentes disponibles para probar diferentes aspectos de la interfaz de usuario de una aplicación.

En Badoo, decidimos comenzar a agregar pruebas de instantáneas utilizando una de las "herramientas" más populares en este momento para las pruebas de instantáneas: iOSSnapshotTestCase (anteriormente conocido como FBSnapshotTestCase porque inicialmente fue construido y lanzado como fuente abierta por Facebook).

Encuentre más información sobre las pruebas de instantáneas y este marco específico en los siguientes enlaces:



Necesitábamos encontrar una forma de probar los componentes que ya teníamos en BadooUIKit para evitar posibles regresiones mientras modificamos los componentes utilizados por el resto de la aplicación.

También queríamos automatizar el proceso de agregar una nueva prueba de instantánea para un componente tanto como sea posible.

Como se explicó anteriormente en este artículo, también tenemos una aplicación de galería que enumera todos los componentes y todos los diferentes estados que podría tener un solo componente. Es muy conveniente porque permite agregar las pruebas de instantáneas utilizando Badoo Gallery como la aplicación host.

Todos los componentes de la interfaz de usuario implementados en BadooUIKit se almacenan en una clase (repositorio o patrón de almacenamiento) que proporciona acceso a todos los componentes. Esta tienda se puede instanciar tanto para presentar la lista de componentes en la galería como para acceder a ellos desde las clases de prueba de instantáneas. Esto significa que no es necesario duplicar el trabajo de crear instancias y preparar los diferentes estados de cada componente en el nivel de prueba porque esto ya se ha hecho al introducir el componente en la interfaz de la aplicación de la galería.

Estas son algunas preguntas que pueden surgir con respecto a las pruebas de instantáneas. Permítame proporcionarle algunas respuestas:

¿Dónde se almacenan las imágenes instantáneas?

Los almacenamos directamente en el repositorio de git. Inicialmente pensamos que podría inflar demasiado el tamaño del repositorio, pero resultó no ser tan malo. En la mayoría de los casos, no estamos probando pantallas completas, sino componentes pequeños, por lo que las capturas de pantalla son muy ligeras. Actualmente nuestra carpeta de capturas de pantalla es de alrededor de 11Mb, lo que consideramos aceptable.

¿Se prueban todas las resoluciones posibles en todos los simuladores posibles?

No, el beneficio no sería enorme y podría causar numerosos problemas, incluidas pruebas escamosas, una carpeta de instantáneas más pesada y más dificultades para mantener el conjunto de pruebas. Preferimos ser pragmáticos y solo probar el dispositivo más popular entre nuestros usuarios. Nuestro sistema de integración continua también está configurado para usar un simulador del mismo modelo de dispositivo utilizado para hacer las instantáneas.

¿Son suficientes las pruebas de instantáneas para cubrir toda la interfaz de usuario?

No lo creo En Badoo, también tenemos diferentes tipos de pruebas en diferentes niveles de la aplicación, como por ejemplo, pruebas funcionales (utilizamos marcos de trabajo de Calabash y KIF) y algunas pruebas de integración. En mi experiencia, es importante encontrar un buen equilibrio entre el tipo de pruebas y la cantidad de pruebas necesarias para satisfacer los requisitos de cualquier aplicación.

Lecciones aprendidas


Por supuesto, durante el proceso de construcción de esta nueva plataforma, nuestra compañía ha aprendido muchas cosas y todavía estamos aprendiendo con cada iteración. Todas las herramientas y procesos anteriores se introdujeron en un período de aproximadamente 12 meses y todavía están evolucionando. Hasta ahora, cada paso ha resultado positivo tanto para los desarrolladores como para la empresa, y desde el principio comenzamos a ver resultados positivos. Estas son algunas de las lecciones que aprendimos durante este proceso:

  • Mover todos los componentes existentes a la vez es una tarea muy grande, pero crear el sistema de diseño y alentar al equipo a usarlo como parte del flujo de desarrollo aumenta el número de componentes de la interfaz de usuario paso a paso. Mover algunos componentes en cada tarea que implementan algunos desarrolladores no solo aumenta automáticamente la cantidad de elementos de la interfaz de usuario en su sistema, sino que también desbloquea y libera algunas dependencias entre los elementos existentes. Esto facilita la tarea de mover más y más componentes más adelante.
  • Aprendimos que los diseñadores están felices de reutilizar los componentes existentes, pero es más fácil convencerlos si podemos demostrar que ya tenemos un componente totalmente funcional que se comporta de manera muy similar a lo que necesitan.
  • La necesidad de ahorrar tiempo a medio y largo plazo es una realidad. Todos sabemos que por el momento, los tiempos de compilación en los proyectos Swift + Objective-C no son los mejores. La aplicación Badoo Gallery es muy ligera y se compila muy rápido. Hemos aprendido que es mucho mejor implementar los componentes de la interfaz de usuario directamente usando la aplicación de la galería como área de juegos y luego usarlos desde la aplicación principal donde los tiempos de compilación no son tan rápidos.
  • Tener los componentes en un UIKit específico y una aplicación de galería donde podemos probar fácilmente los componentes aumenta todo el proceso de prueba y nos permite escribir pruebas más fácilmente.


Yendo más lejos - Cosmos


En Badoo nos preocupamos por todas nuestras funciones y queremos que tengan una interfaz de usuario unificada y visualmente atractiva para brindarles a nuestros usuarios la mejor experiencia de calidad al usar todas nuestras plataformas. Es por eso que estamos haciendo cambios globales, con la ayuda de los equipos de diseño y producto, en toda la empresa e implementando un sistema de diseño llamado Cosmos.



Cristiano Rastelli ha escrito varios artículos interesantes donde explica en detalle cómo Cosmos nació. ¡No te los pierdas!

Agradecimientos


Este proyecto no fue un trabajo de un solo hombre: todo el equipo de iOS, incluidos los gerentes, desarrolladores y QA, participaron de una forma u otra. Tengo que agradecerles a todos porque puedo decir que todos estaban a bordo desde el principio.

Gracias al increíble equipo de diseño de Badoo que siempre está dispuesto a hacer un esfuerzo adicional cuando se trata de mejorar los procesos de diseño en toda la empresa.

Un agradecimiento especial a Alexander Zimin por las múltiples mejoras y por su asistencia a tantas reuniones en este proceso, así como por apoyarme personalmente en esta aventura de UI. También a Alyssa Ordillano por sus excelentes gráficos que han mejorado enormemente la accesibilidad de este artículo.

Source: https://habr.com/ru/post/440920/


All Articles