Monorepositório com Swift: organização de código na prática

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course
```html

Monorepositório com Swift: organização de código na prática



No desenvolvimento moderno para iOS e macOS, a escolha da estratégia de gerenciamento de código é um dos principais fatores que afetam a escalabilidade, a velocidade de entrega e a qualidade do produto. Tradicionalmente, os desenvolvedores usavam multirrepositórios (polyrepo), onde cada módulo ou serviço vive em um repositório Git separado. No entanto, com o crescimento de projetos e equipes, surge cada vez mais a questão: como organizar o código para que ele permaneça coeso, reutilizável e facilmente mantível? A resposta é — monorepositório (monorepo) com Swift. Neste artigo, vamos analisar o que é um monorepositório, por que ele é adequado para projetos Swift e como organizá-lo na prática usando o Swift Package Manager (SPM).



O que é um monorepositório e por que ele é necessário em Swift?



Monorepositório é uma abordagem onde todo o código do projeto (ou de vários projetos relacionados) é armazenado em um único repositório. Ao contrário do polyrepo, onde cada componente é isolado, o monorepo une bibliotecas, aplicativos, testes, configurações e documentação sob um único controle de versão.



Para desenvolvedores Swift, o monorepositório é especialmente relevante por várias razões:

  • Versão única de dependências: Você evita a dessincronização de versões de bibliotecas entre diferentes aplicativos.
  • Simplificação de refatoração: Alterações em um módulo comum são imediatamente visíveis para todos os consumidores dentro do repositório.
  • Integração rápida: Novas funcionalidades podem ser testadas e lançadas em um único pull request.
  • Compatibilidade com SPM: O Swift Package Manager é ideal para monorepositórios, pois suporta pacotes locais e caminhos relativos.


Estrutura de um monorepositório para um projeto Swift



Vamos considerar um exemplo prático. Suponha que temos um aplicativo para iOS (em SwiftUI) e macOS (em AppKit), que usam módulos comuns: camada de rede, lógica de autenticação e componentes de UI. Vamos organizar o monorepositório da seguinte forma:



MyMonorepo/├── Package.swift├── Sources/│   ├── AppiOS/│   │   └── main.swift│   ├── AppMacOS/│   │   └── main.swift│   ├── CoreNetworking/│   │   ├── Sources/│   │   │   └── HTTPClient.swift│   │   └── Tests/│   ├── CoreAuth/│   │   ├── Sources/│   │   │   └── AuthService.swift│   │   └── Tests/│   └── UIComponents/│       ├── Sources/│       │   └── CustomButton.swift│       └── Tests/├── Tests/│   ├── AppiOSTests/│   └── AppMacOSTests/├── .gitignore└── README.md


O arquivo chave é Package.swift. Ele descreve todos os módulos e suas dependências. Exemplo desse arquivo:



// swift-tools-version:5.9import PackageDescription

let package = Package( name: "MyMonorepo", platforms: [ .iOS(.v17), .macOS(.v14) ], products: [ .executable(name: "AppiOS", targets: ["AppiOS"]), .executable(name: "AppMacOS", targets: ["AppMacOS"]), .library(name: "CoreNetworking", targets: ["CoreNetworking"]), .library(name: "CoreAuth", targets: ["CoreAuth"]), .library(name: "UIComponents", targets: ["UIComponents"]) ], dependencies: [ // Dependências externas, se necessário // .package(url: "https://github.com/...", from: "1.0.0") ], targets: [ .executableTarget( name: "AppiOS", dependencies: ["CoreNetworking", "CoreAuth", "UIComponents"], path: "Sources/AppiOS" ), .executableTarget( name: "AppMacOS", dependencies: ["CoreNetworking", "CoreAuth", "UIComponents"], path: "Sources/AppMacOS" ), .target( name: "CoreNetworking", dependencies: [], path: "Sources/CoreNetworking/Sources" ), .target( name: "CoreAuth", ```

Blogs

Book Recommendations