Monorepo avec Swift : organisation du code pour iOS et macOS

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Introduction : pourquoi un monorepo en Swift ?



Le développement iOS et macOS est souvent confronté à un dilemme : comment organiser le code pour qu'il reste évolutif, réutilisable et facile à maintenir ? L'approche traditionnelle avec plusieurs dépôts distincts (multirepo) entraîne une fragmentation, une duplication des dépendances et des difficultés de coordination des changements. La solution est le monorepo (monorepository).



Un monorepo est un dépôt unique contenant tous les composants du projet : applications, bibliothèques, outils de build et configurations. Pour l'écosystème Swift, cette approche est particulièrement pertinente grâce à Swift Package Manager (SPM), qui, depuis la version 5.3+, prend parfaitement en charge les packages locaux et l'architecture modulaire.



Dans cet article, nous allons voir comment organiser un monorepo pour des projets Swift, examiner la structure, les outils (Tuist, XcodeGen) et les meilleures pratiques avec des exemples de code.



1. Avantages du monorepo pour Swift



Avant de passer à l'implémentation, examinons les principaux avantages :



  • Version unique des dépendances — tous les modules utilisent la même version des bibliothèques, éliminant les conflits.
  • Commits atomiques — un changement d'API dans un package se répercute immédiatement sur tous les modules dépendants, sans nécessité de synchronisation entre les dépôts.
  • Simplification du CI/CD — un seul pipeline, une seule configuration, mise en cache des builds.
  • Réutilisation du code — les utilitaires communs, modèles, couches réseau sont facilement accessibles pour toutes les cibles (iOS, macOS, watchOS).
  • Code review — les modifications dans différentes parties du projet sont visibles dans une seule PR.


Cependant, il y a aussi des inconvénients : la taille du dépôt, le temps de clonage, la nécessité d'une structure bien pensée. Mais pour les équipes de taille moyenne et plus, le monorepo s'avère souvent être le choix optimal.



2. Structure d'un monorepo en Swift



Examinons une structure typique pour un projet comprenant une application iOS et une application macOS avec une bibliothèque partagée :



MyProject/├── Apps/│   ├── iOSApp/│   │   ├── Sources/│   │   │   └── AppDelegate.swift│   │   ├── Resources/│   │   └── Package.swift│   └── macOSApp/│       ├── Sources/│       │   └── AppDelegate.swift│       ├── Resources/│       └── Package.swift├── Packages/│   ├── Core/│   │   ├── Sources/│   │   │   ├── Core.swift│   │   │   └── Extensions/│   │   ├── Tests/│   │   └── Package.swift│   ├── Networking/│   │   ├── Sources/│   │   │   └── NetworkManager.swift│   │   ├── Tests/│   │   └── Package.swift│   └── UIComponents/│       ├── Sources/│       │   └── CustomButton.swift│       ├── Tests/│       └── Package.swift├── Tools/│   └── Scripts/│       └── build.sh├── .github/│   └── workflows/│       └── ci.yml├── Package.swift (racine)├── Tuist.swift (si nous utilisons Tuist)└── README.md


Explication de la structure :

  • Apps/ — répertoire contenant les applications finales. Chaque application est un package Swift distinct qui dépend des packages dans Packages/.
  • Packages/ — toutes les bibliothèques et modules internes. Chaque package a son propre Package.swift et peut être testé indépendamment.
  • Tools/ — scripts de build, linters, génération de code.
  • Le Package.swift racine (ou la configuration Tuist/XcodeGen) — décrit le workspace et les liens entre les packages.


2.1 Exemple de Package.swift racine (SPM)



// swift-tools-version:5.9import PackageDescription

let package = Package( name: "MyProject", platforms: [ .iOS(.v16), .macOS(.v13) ], products: [ .library(name: "Core", targets: ["Core"]), .library(name: "Networking", targets: ["Networking"]), .library(name: "UICompon

Blogs

Book Recommendations