Actualización de la interfaz de usuario con Combine Segunda parte

Andres Felipe Ocampo
4 min readSep 17, 2021

--

Asignar directamente la salida de un publisher con assign (to: on :)

En el Artículo anterior nos quedamos con un el siguiente codigo:

La propiedad .txt de la UIlabel en este ejemplo asigna siempre una nueva cadena que refleja el satus actual de la batería del coche. Si expandimos un poco más e introducimos una View y un ViewModel:

He omitido un código repetitivo e irrelevante aquí, como los inicializadores de CocheStatusView y el código necesario para agregar un manejador de tap al botón en el controlador de vista. De cualquier manera, estoy seguro de que el código anterior no debería depararte muchas sorpresas. Independientemente de si estás familiarizado con MVVM e independientemente de si cree que este es un buen ejemplo de MVVM. La razón principal por la que he usado un modelo de vista en este ejemplo es para agregar una capa entre el coche que tiene la propiedad @Published y la etiqueta que, en última instancia, mostrará la cantidad de energía de la batería que queda en la batería del coche.

Debido a que, en última instancia, queremos que el modelo de vista en este código prepare una cadena para la etiqueta, el modelo de vista necesitará suscribirse al @Published kwhInBattery del coche y exponer un nuevo editor para enviar cadenas formateadas a la etiqueta. Podemos hacer esto agregando la siguiente propiedad al modelo de vista:

Este código define una propiedad lazy. Esto significa que no se inicializará hasta la primera vez que se lea. Observa que el valor de la propiedad está envuelto en {…} (). Esto significa que queremos inicializar esta propiedad con el resultado del código entre las { .. }. La razón por la que batterySubject es lazy se debe al hecho de que necesitamos acceder a la propiedad del coche para crear el batterySubject. Si no hacemos que batterySubject sea lazy, el código no se compilará porque self no se inicializaría cuando se inicializara batterySubject.

la variable batterySubject es un AnyPublisher <String?, Never> Creamos este publisher tomando el editor $kwhEnBateria del coche, mapeándolo para convertir la caraga de la bateria en un String y borrando el resultado en AnyPublisher usanod .eraseToAnyPublisher() para asegurarnos de que tenemos un tipo limpio para este publisher. ¿El motivo por el que el tipo de valor del editor es String?(opcional) y no String(no opcional) se aclarará en un momento.

Ahora que tenemos una propiedad a la que suscribirnos en el modelo de vista, es el momento de suscribirse al publisher del viewModel en la view. Para hacer esto, necesitamos actualizar el método setupLabel () vacío del controlador de vista del fragmento de código anterior:

Observa lo limpio que es este código. Al utilizar un nuevo suscriptor del que no he hablado antes, no es necesario que proporcionemos cierres ni procesemos la salida del viewModel. En cambio, los valores publicados por batterySubject se asignan a la propiedad de texto de la etiqueta inmediatamente. Para hacer esto, el texto de la etiqueta y la salida de batterySubject deben coincidir. ¿Dado que el texto es una cadena ?, ¿necesitábamos usar una cadena? como tipo de salida para batterySubject.

Espero que esta sea una limitación en Combine que podría eliminarse en versiones futuras, pero a partir de ahora no hay mucho más que podamos hacer.

El operador assign (to: on :) en Combine es similar a sink. Crea un nuevo suscriptor y devuelve un AnyCancellable que debemos conservar para mantener activa la suscripción.

Cuando usas assign (to: on), no proporcionas ningún cierre ni realizas ningún procesamiento adicional en absoluto. En su lugar, todos los valores publicados se asignan a la ruta clave que pasa como on:, en el objeto que pasa como en to:. Ten en cuenta que actualmente existe un problema con la asignación de rutas clave en uno mismo. Hacer esto provocará un ciclo de retención. Puedes leer más sobre este problema, y ​​si está resuelto, en los foros de Swift.

Ahora que has visto cómo puedes tomar un valor publicado de un modelo, modificarlo en un viewModel y asignarlo al texto de una etiqueta usando assign (to: on :), debería scomenzar a ver cómo Combine puede ayudarte a refactorizar tu código de ser la forma antigua e imperativa a la forma nueva y reactiva. Hay muchas formas de lograr tus objetivos, y lo que he demostrado en esta artículo está lejos de ser la única forma de implementar la programación reactiva y MVVM, pero es una forma que funciona para mí, y es bastante simple de explicar y seguir sin dejar se interpone en nuestro objetivo principal, que es aprender Combine.

--

--

Andres Felipe Ocampo
Andres Felipe Ocampo

Written by Andres Felipe Ocampo

Digital Manager and Sr Lead iOS Engineer

No responses yet