iOS Inside #008 - Unificar ou não unificar: o dilema arquitetural dos super apps

Você já ouviu a frase: “vamos juntar todos os apps em um só”.
Parece simples no papel. Mas quem já passou por isso sabe: por trás dessa decisão há uma avalanche de decisões arquiteturais, impactos em build time, modularização, dependências cíclicas, heranças complexas e o bom e velho legado.
Neste episódio, vamos explorar a fundo os bastidores de uma das decisões mais estratégicas (e desafiadoras) no mundo mobile: a unificação de múltiplos produtos dentro de um único app iOS.
O problema real: quando um app não é só um app
Antes de falar de solução, vale a pena entender o porquê dessa unificação acontecer.
Normalmente, ela nasce da combinação de fatores como:
Pressão de negócio: “O cliente não quer baixar vários apps.”
Redução de custos com manutenção e publicação.
Sinergia de marcas ou produtos (ex: um banco unificando sua conta, cartão e benefícios).
Adoção de um app “global” para todos os países, adaptando partes do código para cada mercado.
O problema?
É que, do ponto de vista do código, o que chamamos de unificação muitas vezes é só um acoplamento mal planejado disfarçado de agilidade.
Pontos críticos na arquitetura
Vamos quebrar os principais pontos que você, como dev iOS sênior (ou tech lead), precisa considerar antes de dizer “sim” para a unificação:
1. Modularização ou caos?
Unificar apps sem modularizar é como jogar roupas sujas de três casas diferentes numa mesma gaveta: no começo cabe, depois vira guerra.
O que você precisa fazer:
Separe os domínios em frameworks próprios (Tuist, SPM ou Xcode Project).
Use contracts desacoplados, como
protocols
entre camadas de Features e Core.Adote uma estratégia de Dependency Injection centralizada, evitando singletons globais que crescem fora de controle.
Exemplo:
Você pode criar um módulo RewardsFeatureKit
que expõe apenas um RewardsCoordinatorContract
, desacoplando sua navegação e lógica de UI, e consumido via DI.
2. Adaptabilidade local sem ferir a base global
Esse é o dilema que pode ser vivenciado onde herdamos uma arquitetura de fora e precisávamos adaptá-la ao nosso contexto (sem quebrar o app principal).
Como resolver:
Use herança controlada com classes
open
apenas onde for realmente necessário.Crie subclasses locais com override de comportamentos, mas mantendo os publishers e contracts intactos.
Documente cada sobrescrita, explicando o porquê (e não só o como).
3. Feature Flags & Remote Configs
Com múltiplas funcionalidades coexistindo, o ideal é evitar que cada build seja um Frankenstein.
Use feature flags para:
Habilitar/desabilitar módulos específicos por ambiente ou país.
Testar rollout progressivo de features unificadas.
Adaptar comportamentos sem lançar novas versões.
4. Routing Inteligente com Deep Links & Coordinators
Na unificação, o onboarding de um app pode mudar completamente de outro. Por isso, a navegação precisa ser inteligente e contextual.
Boas práticas:
Tenha um
AppCoordinator
que delega paraFeatureCoordinators
.Use uma
RoutingTable
por produto, com um sistema central de deep linking.Crie testes unitários para validar rotas e suas permissões.
5. Build Time e Escalabilidade
Com o tempo, o app unificado pode passar de 2 minutos para 15 minutos de build.
Isso não é aceitável.
Soluções práticas:
Use Tuist para cache e controle granular dos targets.
Implemente builds por esquema (
AppA-dev
,AppB-prod
, etc.).Modularize até o ponto em que features possam ser desenvolvidas isoladamente.
Desafio de testar classes herdadas
Durante a migração, uma das maiores dores que pode-se enfrentar é testar classes herdadas de outro projeto.
Como lidamos com isso:
Substituímos métodos
open
com comportamento custom via mocks.Usamos
XCTUnwrap
para lidar com injeções via@Injected
.Criamos
protocols
locais que estendem os contracts herdados, isolando as regras de negócio.
“Quando a classe mãe vem com regras que você não controla, o teste precisa isolar o comportamento e simular os estados esperados.”
O alerta final: Unificar é um caminho sem volta
Antes de decidir seguir esse caminho, alinhe:
Como será o ownership das features unificadas?
Quem decide o roadmap se os produtos são diferentes?
O que acontece quando uma feature morre? Quem limpa?
Conclusão
Unificar apps é uma jornada estratégica, não uma simples fusão de código.
Com boas práticas de modularização, DI, testes e routing, é possível construir uma arquitetura que sustente múltiplos produtos com elegância.
Mas sem planejamento, o que era para ser um super app, vira um super problema.
Spoiler do próximo episódio:
Vamos falar sobre como a Apple tem reorganizado suas APIs para incentivar consistência de navegação no iOS, e como isso impacta apps que se tornam verdadeiras plataformas.
#iOSInside #ArquiteturaiOS #SwiftDev #Modularizacao #SuperApps #CleanArchitecture #Tuist #iOSDevelopment
Subscribe to my newsletter
Read articles from iOS Inside directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
