Nous avons eu le même problème et nous l'avons résolu. Deux fois.
Construction incrémentielle (même machine de construction):
avant: ~ 10m après: ~ 35s
COMMENT?
Commençons par notre expérience d'abord. Nous avions un énorme projet Swift / Obj-C et c'était la principale préoccupation: les temps de construction étaient lents et vous deviez créer un nouveau projet pour implémenter une nouvelle fonctionnalité (littéralement). Points bonus pour une coloration syntaxique qui ne fonctionne jamais.
Théorie
Pour vraiment résoudre ce problème, vous devez vraiment comprendre comment fonctionne le système de génération. Par exemple, essayons cet extrait de code:
import FacebookSDK
import RxSwift
import PinLayout
et imaginez que vous utilisez toutes ces importations dans votre fichier. Et aussi ce fichier dépend d'un autre fichier, qui dépend d'une autre bibliothèque, qui à son tour utilise une autre bibliothèque, etc.
Donc, pour compiler votre fichier, Xcode doit compiler chaque bibliothèque que vous avez mentionnée et chaque fichier dont il dépend, donc si vous changez l'un des fichiers "de base", Xcode doit reconstruire littéralement le projet entier.
La construction Xcode est multithread , mais elle se compose de nombreuses arborescences monothread .
Donc, à la première étape de chaque construction incrémentielle, Xcode décide quels fichiers doivent être recompilés et crée une arborescence AST . Si vous modifiez un fichier qui agit comme " fiable " sur d'autres fichiers, tous les autres fichiers qui agissent comme " dépendants " doivent être recompilés.
Le premier conseil est donc de réduire le couplage . Les parties de votre projet doivent être indépendantes les unes des autres.
Pont Obj-C / Swift
Problème avec ces arbres si vous utilisez un pont Obj-C / Swift, Xcode doit passer par plus de phases que d'habitude:
Monde parfait:
- Construit le code Obj-C
- Construire du code Swift
Pont Obj-C / Swift:
- [ÉTAPE RÉPÉTABLE] Construisez le code Swift, qui est nécessaire pour compiler le code Obj-C
- [ÉTAPE RÉPÉTABLE] Construisez le code Obj-C, qui est nécessaire pour compiler le code Swift
- Répétez 1 et 2 jusqu'à ce qu'il ne vous reste que du code Swift et Obj-C non fiable
- Construire le code Obj-C
- Construire du code Swift
Donc, si vous changez quelque chose de l'étape 1 ou 2, vous êtes fondamentalement en difficulté. La meilleure solution consiste à minimiser Obj-C / Swift Bridge (et à le supprimer de votre projet).
Si vous n'avez pas de pont Obj-C / Swift, c'est génial et vous êtes prêt à passer à l'étape suivante:
Swift Package Manager
Il est temps de passer à SwiftPM (ou au moins de mieux configurer vos Cocoapods).
Le fait est que la plupart des frameworks avec la configuration par défaut des Cocoapods traînent avec eux-mêmes beaucoup de choses dont vous n'avez pas besoin.
Pour tester cela, créez un projet vide avec une seule dépendance comme PinLayout, par exemple et essayez d'écrire ce code avec Cocoapods (configuration par défaut) et SwiftPM.
import PinLayout
final class TestViewController: UIViewController {
}
Spoiler: Cocoapods compilera ce code, car Cocoapods importera CHAQUE IMPORTATION de PinLayout (y compris UIKit) et SwiftPM ne le fera pas parce que SwiftPM importe les frameworks atomiquement.
Hack sale
Vous souvenez-vous que la construction Xcode est multi-thread?
Eh bien, vous pouvez en abuser si vous pouvez diviser votre projet en plusieurs éléments indépendants et les importer tous en tant que cadres indépendants dans votre projet. Cela réduit le couplage et c'était en fait la première solution que nous avons utilisée, mais ce n'était pas très efficace, car nous ne pouvions réduire le temps de construction incrémentiel qu'à ~ 4-5 m, ce qui n'est RIEN par rapport à la première méthode.