Design de software

Padrão Observer em Swift: do NotificationCenter ao Combine

Ao criar um app iOS, você inevitavelmente encontra esta situação: algo muda na tela A, e uma tela B, distante, também precisa ser atualizada.

3 min de leitura
Imagem de capa de Padrão Observer em Swift: do NotificationCenter ao Combine

Ao criar um app iOS, você inevitavelmente encontra esta situação: algo muda na tela A, e uma tela B, distante, também precisa ser atualizada.

Ao conectar telas à força usando delegates, o código pode se enroscar como espaguete.

É aí que entra o padrão Observer. Em Swift, o caminho mais natural é começar com NotificationCenter e depois migrar para Combine.

Neste artigo, vamos entender o padrão Observer, aprender a usar NotificationCenter e conhecer o Combine, cada vez mais usado, com código real.

O que é o padrão Observer?

O padrão Observer é uma estrutura que notifica automaticamente os objetos que observam um determinado objeto quando seu estado muda.

Pense nas inscrições do YouTube. Quando um canal (publicador) publica um vídeo, os inscritos (observadores) recebem uma notificação.

O ponto principal é que o publicador e os observadores não precisam conhecer uns aos outros diretamente.

Publicador e observadores trocam notificações sem se conhecer
Publicador e observadores trocam notificações sem se conhecer

O canal não se importa com quantos inscritos existem nem com quem eles são. Ele apenas anuncia: “Vídeo novo no ar”.

Essa conexão flexível reduz os emaranhados no código e facilita muito as alterações futuras.


Como usar o NotificationCenter?

NotificationCenter é a ferramenta integrada da Apple para o padrão Observer. Você pode usá-la diretamente, sem bibliotecas adicionais.

Primeiro, defina o nome da notificação e escreva o código do publicador.

// Definir o nome da notificação
extension Notification.Name {
    static let didLogin = Notification.Name("didLogin")
}

// Publicar notificação quando o login for bem-sucedido
NotificationCenter.default.post(name: .didLogin, object: nil)

No lado receptor, registre um observador desta forma.

// Assinar a notificação
NotificationCenter.default.addObserver(
    self, selector: #selector(handleLogin),
    name: .didLogin, object: nil
)

Há um ponto importante: a abordagem antiga (addObserver + selector) pode causar problemas se você não chamar removeObserver quando a tela desaparecer.

Desde o iOS 9, mais partes são limpas automaticamente, mas, ao usar APIs baseadas em blocos, gerencie o token retornado.


O que há de bom em migrar para o Combine?

Combine é um framework de programação reativa apresentado pela Apple em 2019. Ele pode ser usado a partir do iOS 13.

Também é possível converter NotificationCenter em um Publisher do Combine, integrando-o naturalmente ao código existente.

// NotificationCenterpara a abordagem  Combine 
let token = NotificationCenter.default
    .publisher(for: .didLogin)
    .sink { _ in
        print("Detectar login!")
    }

A grande vantagem do Combine é poder encadear fluxos de dados.

Você pode transformar valores com operadores como map e filter e combinar vários eventos.

Ao guardar em uma variável a assinatura (AnyCancellable) retornada por sink, ela é cancelada automaticamente quando a variável desaparece. A gestão de memória fica muito mais simples.

Eu peguei o jeito deixando o código aberto e escrevendo tudo à mão
Eu peguei o jeito deixando o código aberto e escrevendo tudo à mão

Então, qual usar?

Depende da situação. Organizei tudo na tabela abaixo.

Item NotificationCenter Combine
Momento de adoção API integrada antiga iOS 13+
Dificuldade de aprendizado Baixa Média ou maior
Transformação de valores Difícil Flexível com map/filter
Gestão de memória Cuidar manualmente Automática ao armazenar a assinatura

Para uma ou duas notificações simples, o NotificationCenter é suficiente.

Por outro lado, se o fluxo de dados for complexo ou você precisar combinar vários eventos, o Combine é muito mais limpo.

Se você está começando, aprenda o conceito com NotificationCenter e migre para Combine quando se sentir confortável.

É claro que SwiftUI e async/await estão em alta hoje, então também vale considerá-los em projetos novos.

É muito gratificante quando uma notificação atualiza outra tela também
É muito gratificante quando uma notificação atualiza outra tela também

Resumo

Hoje vimos o padrão Observer em Swift, do NotificationCenter ao Combine.

Não tente entender tudo perfeitamente desde o início. Comece criando uma pequena notificação. Quando você escreve com as próprias mãos, pega o jeito muito mais rápido. Estou torcendo por você!

Continue lendo