Diseño de software

Patrón Observer en Swift: de NotificationCenter a Combine

Al crear una app de iOS, tarde o temprano aparece esta situación: algo cambia en la pantalla A y una pantalla B, muy alejada, también debe actualizarse.

3 min de lectura
Imagen de portada de Patrón Observer en Swift: de NotificationCenter a Combine

Al crear una app de iOS, tarde o temprano aparece esta situación: algo cambia en la pantalla A y una pantalla B, muy alejada, también debe actualizarse.

Si conectas las pantallas a la fuerza mediante delegados, el código puede enredarse como un plato de espaguetis.

Ahí entra el patrón Observer. En Swift, lo más natural es empezar con NotificationCenter y pasar después a Combine.

En este artículo veremos qué es el patrón Observer, cómo usar NotificationCenter y cómo trabajar con Combine, cada vez más usado, mediante código real.

¿Qué es el patrón Observer?

El patrón Observer es una estructura que avisa automáticamente a los objetos que observan un sujeto cuando cambia su estado.

Piensa en las suscripciones de YouTube. Cuando un canal (publicador) sube un vídeo, los suscriptores (observadores) reciben una notificación.

La clave es que el publicador y los observadores no necesitan conocerse directamente.

El publicador y los observadores intercambian notificaciones sin conocerse
El publicador y los observadores intercambian notificaciones sin conocerse

Al canal no le importa cuántos suscriptores hay ni quiénes son. Solo anuncia: «He subido un vídeo».

Esta conexión flexible evita que el código se enrede y facilita mucho las modificaciones posteriores.


¿Cómo se usa NotificationCenter?

NotificationCenter es la herramienta integrada de Apple para el patrón Observer. Puedes usarla directamente, sin bibliotecas adicionales.

Primero define el nombre de la notificación y escribe el código del publicador.

// Definir el nombre de la notificación
extension Notification.Name {
    static let didLogin = Notification.Name("didLogin")
}

// Publicar una notificación cuando el inicio de sesión tenga éxito
NotificationCenter.default.post(name: .didLogin, object: nil)

En el lado receptor, registra un observador así.

// Suscribirse a la notificación
NotificationCenter.default.addObserver(
    self, selector: #selector(handleLogin),
    name: .didLogin, object: nil
)

Hay un punto importante: el método antiguo (addObserver + selector) puede causar problemas si no llamas a removeObserver cuando desaparece la pantalla.

Desde iOS 9 se limpian automáticamente más recursos, pero con las API basadas en bloques debes gestionar el token devuelto.


¿Qué ventajas ofrece pasar a Combine?

Combine es un framework de programación reactiva que Apple presentó en 2019. Está disponible desde iOS 13.

NotificationCenter también puede convertirse en un Publisher de Combine, por lo que se integra naturalmente con el código existente.

// NotificationCenteral enfoque  Combine 
let token = NotificationCenter.default
    .publisher(for: .didLogin)
    .sink { _ in
        print("Detectar el inicio de sesión!")
    }

La verdadera ventaja de Combine es que permite encadenar flujos de datos.

Puedes transformar valores con operadores como map y filter, y combinar varios eventos.

Si guardas en una variable la suscripción (AnyCancellable) que devuelve sink, la suscripción se cancela automáticamente cuando desaparece la variable. La gestión de memoria resulta mucho más sencilla.

Yo aprendí practicando mientras dejaba el código abierto y lo escribía a mano
Yo aprendí practicando mientras dejaba el código abierto y lo escribía a mano

Entonces, ¿cuál deberías usar?

Depende de la situación. Lo he resumido en la tabla siguiente.

Elemento NotificationCenter Combine
Momento de adopción API integrada antigua iOS 13+
Dificultad de aprendizaje Baja Media o alta
Transformación de valores Difícil Flexible con map/filter
Gestión de memoria Requiere atención manual Automática al guardar la suscripción

Para una o dos notificaciones sencillas, NotificationCenter es suficiente.

En cambio, si el flujo de datos es complejo o necesitas combinar varios eventos, Combine resulta mucho más limpio.

Si estás empezando, aprende el concepto con NotificationCenter y pasa a Combine cuando te sientas cómodo.

Por supuesto, hoy SwiftUI y async/await son la norma, así que también conviene tenerlos en cuenta en proyectos nuevos.

Cuando una notificación actualiza también otra pantalla, la satisfacción es enorme
Cuando una notificación actualiza también otra pantalla, la satisfacción es enorme

Resumen

Hoy hemos recorrido el patrón Observer de Swift, desde NotificationCenter hasta Combine.

No intentes entenderlo todo a la perfección desde el principio. Empieza creando una pequeña notificación. Al escribirla tú mismo, lo entenderás mucho antes. ¡Ánimo!

Seguir leyendo