EsMontagem com foto de Michael Dziedzic | Unsplash

Arquitetura iOS da Cora

Como estruturamos nossa arquitetura de forma isolada, independente e escalável

Renato Sarro Matos
Published in
4 min readSep 15, 2022

--

Um dos principais objetivos de todo novo projeto é a definição de sua arquitetura. Independente da escolha, problemas e desafios vão surgindo à medida que o projeto progride. A ideia é justamente compartilhar alguns insights que direcionaram as decisões iniciais, os tipos de desafios que enfrentamos e como temos evoluído nossa estrutura.

New Project

Tudo começou em Setembro de 2019. Ao abrirmos o Xcode pela primeira vez para começar a criar os primeiros arquivos, logo nos perguntamos: qual arquitetura utilizaremos?

Após alguns vários anos desenvolvendo softwares, havíamos tido contato com diversos padrões estruturais: MVC, MVP, MVVM, VIPER, Clean Swift — o repertório de escolhas era realmente grande.

Uma coisa que sempre nos chamou a atenção foi o fato de que um projeto começava com um padrão de arquitetura e, conforme ia escalando, ganhando novos recursos e necessidades, ele ia se modificando. Com o tempo, ninguém mais sabia qual era o padrão.

Logo no início, tínhamos um primeiro desafio a ser resolvido, pois queríamos muito achar uma forma de não cair neste problema. A falta de uma definição estrutural clara contribui muito pra que um projeto se torne difícil de manter, escalar, ou até mesmo alterar.

Com isso em mente, analisamos cada padrão disponível e observamos que cada padrão atendia bem a um leque de cenários. Por outro lado, ou eram muitas camadas pra resolver um problema pequeno ou as camadas acabavam ficando muito massivas por conta da complexidade.

A partir daí, fizemos a pergunta: como podemos fazer para termos a flexibilidade de trabalhar com o padrão que faz mais sentido em cada contexto?

Clean Architecture + Domain Driven Design

Estrutura de camadas em forma de cebola, começando do domain e subindo até o application

Com o Clean Swift cada vez mais em alta, acabamos nos deparando com o princípio de tudo, mas tirando um pouco o foco da plataforma e olhando para a situação de forma mais macro.

Partindo deste princípio, temos duas camadas principais que dividem nosso projeto:

Application: contém tudo o que é relacionado à saída, como presentation patterns, templates, elementos de infra etc.

Domain: agrupa tudo o que se relaciona à regra de negócio do projeto. Fluxo de requests, regras de acesso, persistência de dados etc.

Estrutura mostrando como os use cases se relacionam com presentation e domain

Essa estrutura de projeto nos permite termos muita flexibilidade em cada contexto. Por exemplo: em nossa camada de apresentação — dentro de Application — podemos trabalhar com vários patterns de acordo com cada contexto, evitando assim ter estruturas robustas para implementações simples, ou estruturas massivas para implementações mais complexas.

Image exibindo diferentes presentation patterns dentro da nossa arquitetura (MVVM, MVC e Clean Swift)

Um detalhe específico em relação ao presentation pattern fala sobre a curva de aprendizado e desenvolvimento das pessoas que estão começando. Temos uma cultura de colaboração, mentoria e ensino muito forte. Considerando que cada pessoa está em um momento de sua trajetória, essa flexibilidade também contribui para que pessoas mais novas consigam colaborar diretamente com o projeto, pois conseguem aplicar padrões mais simples que estão tendo mais contato neste início de jornada.

É muito importante reforçar também o uso de interfaces para a aplicação do conceito de inversão de dependência e inversão de controle, evitando o acoplamento entre as partes e possibilitando que cada item possa ser testado de forma individual. Eventualmente, se for preciso fazer alguma alteração, ela será contextualizada sem causar atrito em outras partes.

Controle de Fluxo

Imagem mostrando o fluxo de relação entre coordinators, child coordinators e views

Um outro ponto importante na definição da nossa estrutura é a padronização na inicialização de fluxos. Em muitos projetos, é muito comum encontrar diversas formas de apresentar uma tela, principalmente em projetos que possuem uma convivência entre Storyboards e ViewCode.

Tendo isso em mente, criamos uma estrutura de Coordinators utilizando o pattern Cadeia de Responsabilidade e eventos.

Essa estrutura permite que uma view envie um evento sem saber quem vai tratá-lo, centralizando a inicialização de fluxo ou tela em um único entry point.

Esta é uma visão macro de nossa arquitetura. Em breve, entraremos de forma mais detalhada nos presentation patterns que utilizamos e como eles se comportam dentro dessa estrutura.

Que tal interagir clicando nos claps (de 1 a 50) pra mostrar que curtiu o texto? 👏

Você também pode acessar nossa Página de Carreiras pra saber mais sobre nossas vagas e acompanhar a gente no Linkedin e no Instagram de Corajosers.

--

--

Renato Sarro Matos
Cora
Writer for

iOS Lead na Cora, metido a músico e apreciador da arte do tricô