Combine(Outdated)

Vinicius Mangueira
Popcodemobile
Published in
6 min readJun 16, 2020
Resultado de imagem para Combine Swift

Assim como RxSwift revolucionou o mundo da programação reativa no Swift, a Apple, em sua última conferência, lançou de surpresa um framework para a mesma função chamado Combine.

O Combine vira totalmente o jogo para o mundo de desenvolvimento nativo iOS, pois dá suporte nativo de forma explicita a reatividade. Agora podemos estabelecer uma estrutura assíncrona nativa no Swift dando-nos o poder de descartar dependências de estruturas reativas de terceiros e fazer tudo com suporte nativo da linguagem.

Como é notório o crescimento do uso de reatividade nos dias de hoje dos desenvolvedores, com muitas linguagens e frameworks dando suporte a esse tipo de feita, agora o Swift não fica nada atrás.

Por que estudar o Combine?

O Combine com o SwiftUI promete mudar muito a figura do mercado iOS, como várias linguagens e frameworks agora a Apple tem seu próprio framework de reatividade, ficando muito mais fácil de manter e trabalhar com processamento de eventos.

Agora que já sabemos do que se trata, vamos entender um pouco mais sobre o framework e como utilizará-lo.

A estrutura Combine fornece uma API Swift declarativa para processar valores ao longo do tempo. Esses valores podem representar eventos da interface do usuário, respostas de rede, eventos planejados e muitos outros tipos de dados assíncronos. O Combine declara publishers para expor valores que podem mudar ao longo do tempo e subscribers para receber esses valores dos editores.

Publishers

O Publisher é um protocolo que declara um tipo que pode enviar uma sequência de valores ao longo do tempo de forma assíncrona, tendo operadores para agir de acordo com os valores recebidos e republicá-los.

Por debaixo dos panos o Publisher é um protocolo que tem um tipo associado referente a saída e entrada que serão registradas com um subscriber (o qual veremos mais a frente), e outro tipo associado referente á uma possível falha sendo do tipo Error. Dentro do protocolo temos uma função genérica receive que ira receber um evento que no caso é um subscriber e anexará no publisher, para que esses valores possam ser manipulados.

O protocolo tem várias extensões com diversas funções para que você possa registrar ou agenda o registro de um evento e vários métodos que podem ser explorados para cada ação ou evento que você deseja manipular. Caberia um artigo só para falar um pouco mais sobre o Publisher.

O nosso publisher será responsável por escutar e saber o que se passa nesses eventos e valores registrados, para quem está mais familiarizado com Rx Swift seria basicamente os Observables.

Subscribers

O Subscriber é um protocolo que declara um tipo associado de entrada ou saída de um publisher. Otipo associado input seriam os valores que cada subscriber pode receber e propagar para o publisher, o qual também possui uma função receive que informa ao subscriber que o publisher produziu um evento.

Cancellable

O Cancellable é um protocolo que indica a ação ou quando um evento foi cancelado. Quando o cancel() é chamado ele libera todos os recursos alocados, liberando por sua vez todos eventos referentes aquele Publisher que veio ser registrado. Sendo assim, o evento que foi registrado é cancelado. Caso você consumisse uma API e mostrasse isso ao usuário e o mesmo tivesse a opção de listar os favoritos dele seria possível tratar esse efeito colateral fazendo um Subscribe no evento, porém se ele apertar o botão para não mostrar mais só os favoritos, poderia ser feito um cancel() no evento, utilizando o Cancellable.

Subject, PassthroughSubject, ObservableObject:

Agora vamos colocar a mão na massa para entendermos como funciona os termos acima que são de suma importância, e cruciais na hora do desenvolvimento.

SwiftUI

No exemplo utilizaremos SwiftUI que é um novo framework da Apple para criar interfaces de usuário de forma simples, menos verbosa e mais coesa. Então se você não tem nenhum tipo de familiaridade com SwiftUI postaremos algo aqui sobre o mesmo, porém enquanto isso você pode clicar aqui.

Hands On

De início teremos o objetivo de listar uma série de programas de TV que estão em alta, para isso utilizaremos da reativa do Combine e criaremos toda interface usando SwiftUI. Como Back-End usaremos a própria API da Apple do Itunes para listar as últimas séries. Clique aqui para saber mais sobre API.

Para seguir o modelo da API criaremos um modelo FeedGroup tendo: 1) um Feed que implementa Decodable e 2) um Feed sendo Decodable contendo um título e uma sequência de resultados representando os resultados da API. No FeedResult além de implementar o Decodable implementamos o Identifiable, o qual nos obriga a ter um id, que é o nosso identificador de todo objeto pertencendo ao tipo FeedResult.

Na figura acima criamos uma classe chama Service que será responsável por tudo consumo da API e funções que as delegam a mesma responsabilidade para assim seguir o primeiro princípio do SOLID.

Você pode notar que a classe implementa o BindableObject, que é um protocolo para criar um Binding dentro daquele objeto, ou seja, ele pode receber eventos referentes a valores e tem como tipo associado um associated type de Publisher. O BindableObject nos obriga a implementar uma variável chamada didChange, que é um PublisherType.

Aqui quando criamos nosso didChange dizemos que ele é um Subject, ou melhor, um PassthroughSubject. Um Subject é um Publisher que propaga um evento para fora de outros elementos que foram publicados, já o PassthroughSubject é um subject que passa valores e também uma completion, no caso o responsável por essa alteração é o nosso próprio service, por isso assinamos ele no genérico do Subject.

Criamos uma chamada feedResult, um tipo de coleção de FeedResult, sendo uma computada com um didSet, que será o valor setado na inicialização da computada com o nosso Subject a qual propagará e enviará a alteração do evento.

No nosso init temos o padrão para o consumo de API, porém note que utilizamos uma chamada assíncrona e nisso setamos que o nosso feedResult será igual á o results que consumimos da API. Logo, toda vez nossa computada passar por alteração, até mesmo em tempo de execução, nosso valor será atualizado.

Na nossa ContentView basta criarmos uma instância do tipo Service declarando o ‘@State ‘, indicando assim que o valor pode ser alterado com os nossos Publishers para utilizarmos o service.feedResult na nossa lista passando por cada item da API consumida e mostrando em tempo de execução, já que se essa lista pode sofrer algum tipo de alteração, que ela será construída novamente em tempo de execução, tendo em vista que nosso service possuí um estado de mutabilidade.

Dessa forma nosso exemplo ficará como mostra a figura abaixo:

No repositório listado nas referências você pode ver todo o fonte.

Swift Combine X Rx Swift

Para entender um pouco mais sobre as diferenças e semelhanças leia esse artigo.

Se você chegou até aqui esperamos que tenha aprendido um pouco mais sobre Swift Combine.

Para seguir exemplo de código você pode conferir aqui: https://github.com/ViniciusDeep/WWDC-Challenge

Referências:

https://developer.apple.com/documentation/combine

https://medium.com/gett-engineering/rxswift-to-apples-combine-cheat-sheet-e9ce32b14c5b

Combine: Asynchronous Programming with Swift by: raywenderlich.com

--

--

Vinicius Mangueira
Popcodemobile

I'm Mobile developer who loves to learn about new web and mobile technologies. I combine my Computer Science studies with my soft skils