Aula 93: Publicadores e Assinantes no Combine
Combine é uma poderosa framework em Swift que permite aos desenvolvedores trabalharem com eventos assíncronos usando uma API declarativa em Swift. Ela é composta por dois componentes principais: Publicadores e Assinantes. Nesta aula, exploraremos esses componentes, demonstraremos como eles funcionam e forneceremos exemplos para ilustrar seu uso.
O que é um Publicador?
Um Publicador é responsável por emitir uma sequência de valores ao longo do tempo. Ele representa a fonte de dados que pode ser observada. Publicadores podem emitir um ou muitos valores e podem também ser finalizados com sucesso ou falhar com um erro.
Exemplo de um Publicador Simples
Vamos criar um publicador simples que emite uma sequência de números inteiros.
import Combine
// Cria um publicador que emite valores de 1 a 5
let publicador = (1...5).publisher
// Inscreve-se no publicador
let cancelável = publicador
.sink(receiveCompletion: { conclusão in
switch conclusão {
case .finished:
print("Publicador foi finalizado com sucesso.")
case .failure(let erro):
print("Publicador falhou com erro: \(erro)")
}
}, receiveValue: { valor in
print("Valor recebido: \(valor)")
})
No exemplo acima, usamos o método publisher
em um intervalo de inteiros para criar um publicador. A função sink
inscreve-se neste publicador, fornecendo um fechamento para gerenciar os valores recebidos e eventos de conclusão.
O que é um Assinante?
Um Assinante é a entidade que escuta os valores emitidos por um Publicador. Ele reage a valores recebidos e eventos de conclusão. Implementar um Assinante permite que lidemos com os dados enviados pelo Publicador.
Criando um Assinante Personalizado
Combinar o uso de um Assinante personalizado pode mostrar como você pode implementar sua própria lógica de inscrição:
import Combine
// Cria um assinante personalizado
class AssinantePersonalizado: Subscriber {
typealias Input = Int
typealias Failure = Never
func receive(subscription: Subscription) {
print("Assinante recebeu a assinatura.")
// Solicita receber valores
subscription.request(.unlimited)
}
func receive(_ input: Int) -> Subscribers.Demand {
print("Assinante recebeu o valor: \(input)")
return .none
}
func receive(completion: Subscribers.Completion<Never>) {
print("Assinante recebeu a conclusão.")
}
}
// Cria uma instância do AssinantePersonalizado
let assinantePersonalizado = AssinantePersonalizado()
// Usa-o para se inscrever em um publicador
let publicadorInteiros = (1...5).publisher
publicadorInteiros.subscribe(assinantePersonalizado)
Neste exemplo, definimos uma classe AssinantePersonalizado
que implementa o protocolo Subscriber
. Ele processa a assinatura, os valores recebidos e os eventos de conclusão de acordo com sua lógica definida.
Combinando Publicadores
Combine permite que você utilize vários publicadores juntos, combinando sua saída de maneiras interessantes.
Usando Operadores para Combinar Publicadores
Vamos ver um exemplo usando o operador merge
para combinar múltiplos publicadores:
import Combine
let publicador1 = Just(1)
let publicador2 = Just(2)
// Combina publicadores
let combinado = publicador1.merge(with: publicador2)
// Inscreve-se no publicador combinado
let cancelávelCombinado = combinado
.sink(receiveValue: { valor in
print("Valor recebido do combinado: \(valor)")
})
Neste trecho de código, Just
é um publicador que emite um único valor. Nós combinamos publicador1
e publicador2
usando o operador merge
e nos inscrevemos no publicador resultante que emite valores de ambos os publicadores.
Conclusão
Nesta aula, aprendemos sobre os componentes centrais do Combine: Publicadores e Assinantes. Exploramos como criar publicadores simples, implementar um assinante personalizado e combinar múltiplos publicadores para alcançar fluxos de dados complexos. Combine é uma framework versátil que simplifica o manuseio de eventos assíncronos, tornando seu código mais reativo e de fácil manutenção.
Sinta-se à vontade para experimentar os exemplos e aprofundar-se na framework Combine para aprimorar sua compreensão e conjunto de habilidades na programação em Swift!