Tivemos o mesmo problema e o corrigimos. Duas vezes.
Compilação incremental (mesma máquina de compilação):
antes: ~ 10m depois: ~ 35s
COMO?
Vamos começar com a nossa experiência primeiro. Tivemos um grande projeto Swift / Obj-C e essa era a principal preocupação: os tempos de construção eram lentos e você tinha que criar um novo projeto para implementar um novo recurso (literalmente). Pontos de bônus por destacar a sintaxe que nunca funciona.
Teoria
Para realmente corrigir isso, você precisa entender realmente como o sistema de compilação funciona. Por exemplo, vamos tentar este trecho de código:
import FacebookSDK
import RxSwift
import PinLayout
e imagine que você usa todas essas importações em seu arquivo. E também esse arquivo depende de outro arquivo, que depende de outras bibliotecas, que por sua vez usa outras bibliotecas etc.
Portanto, para compilar seu arquivo, o Xcode precisa compilar todas as bibliotecas mencionadas e todos os arquivos dos quais depende, portanto, se você alterar um dos arquivos "principais", o Xcode precisará reconstruir literalmente todo o projeto.
A construção do Xcode é multithread , mas consiste em muitas árvores de thread único .
Portanto, na primeira etapa de cada compilação incremental, o Xcode decide quais arquivos devem ser recompilados e cria uma árvore AST . Se você alterar um arquivo que está atuando como " confiável " em outros arquivos, todos os outros arquivos que atuam como " dependentes " deverão ser recompilados.
Portanto, o primeiro conselho é diminuir o acoplamento . As partes do seu projeto precisam ser independentes uma da outra.
Ponte Obj-C / Swift
Problema com essas árvores, se você estiver usando uma ponte Obj-C / Swift, o Xcode precisará passar por mais fases do que o habitual:
Mundo perfeito:
- Cria código Obj-C
- Criar código Swift
Ponte Obj-C / Swift:
- [REPEATABLE STEP] Crie código Swift, necessário para compilar o código Obj-C
- [REPEATABLE STEP] Crie código Obj-C, necessário para compilar o código Swift
- Repita 1 e 2 até que você tenha apenas o código Swift e Obj-C não confiável restante
- Criar código Obj-C
- Criar código Swift
Portanto, se você alterar algo da etapa 1 ou 2, estará basicamente com problemas. A melhor solução é minimizar a Obj-C / Swift Bridge (e removê-la do seu projeto).
Se você não possui uma Obj-C / Swift Bridge, isso é incrível e você pode ir para a próxima etapa:
Gerenciador de Pacotes Swift
Hora de mudar para o SwiftPM (ou pelo menos configurar melhor seus Cocoapods).
O fato é que a maioria das estruturas com a configuração padrão do Cocoapods arrasta consigo muitas coisas que você não precisa.
Para testar isso, crie um projeto vazio com apenas uma dependência como PinLayout, por exemplo, e tente escrever esse código com Cocoapods (configuração padrão) e SwiftPM.
import PinLayout
final class TestViewController: UIViewController {
}
Spoiler: o Cocoapods compilará esse código, porque o Cocoapods importará TODAS AS IMPORTAÇÕES do PinLayout (incluindo UIKit) e o SwiftPM não, porque o SwiftPM importa estruturas atomicamente.
Corte sujo
Você se lembra da construção do Xcode com vários threads?
Bem, você pode abusar, se conseguir dividir seu projeto em várias partes independentes e importar todas elas como estruturas independentes para o seu projeto. Ele reduz o acoplamento e essa foi realmente a primeira solução que usamos, mas na verdade não foi muito eficaz, porque só conseguimos reduzir o tempo de construção incremental para ~ 4-5m, o que não é nada comparado ao primeiro método.