У нас була така ж проблема, і ми її вирішили. Двічі.
Поступова збірка (та сама машина для складання):
до: ~ 10м після: ~ 35с
ЯК?
Почнемо спочатку з нашого досвіду. У нас був масштабний проект Swift / Obj-C, і це було головним питанням: час збирання був повільним, і вам довелося створити новий проект, щоб реалізувати нову функцію (буквально). Бонусні бали за неробоче виділення синтаксису.
Теорія
Щоб справді це виправити, ви повинні по- справжньому зрозуміти, як працює система побудови. Наприклад, спробуємо цей фрагмент коду:
import FacebookSDK
import RxSwift
import PinLayout
і уявіть, що ви використовуєте весь цей імпорт у своєму файлі. А також цей файл залежить від іншого файлу, який залежить від інших бібліотек, який, у свою чергу, використовує інші бібліотеки тощо.
Отже, для компіляції вашого файлу Xcode повинен компілювати кожну згадану вами бібліотеку, і кожен файл залежить від цього, тому якщо ви зміните один із "основних" файлів, Xcode має відновити буквально весь проект.
Збірка Xcode багатопотокова , але вона складається з багатьох однониткових дерев .
Отже, на першому кроці кожної інкрементальної збірки Xcode вирішує, які файли потрібно перекомпілювати та будує дерево AST . Якщо ви зміните файл, який діє як " надійний " для інших файлів, тому кожен інший файл, який діє як " залежний ", повинен бути перекомпільований.
Тому перша порада - знизити з'єднання . Ваші частини проекту повинні бути незалежними одна від одної.
Об'є-С / Швидкий міст
Проблема з тими деревами, якщо ви використовуєте міст Obj-C / Swift, Xcode повинен пройти більше фаз, ніж зазвичай:
Ідеальний світ:
- Створює код Obj-C
- Створіть код Swift
Obj-C / Свіфт-міст:
- [ПОВТОРЕННИЙ КРОК] Побудуйте код Swift, який необхідний для компіляції коду Obj-C
- [ПОВТОРЕННИЙ КРОК] Побудуйте код Obj-C, який необхідний для компіляції коду Swift
- Повторюйте 1 і 2, поки у вас не залишиться лише незалежний код Swift & Obj-C
- Побудувати код Obj-C
- Створіть код Swift
Тож якщо ви змінили щось із кроку 1 або 2, ви, в основному, переживаєте проблеми. Найкраще рішення - мінімізувати Obj-C / Swift Bridge (і видалити його зі свого проекту).
Якщо у вас немає Obj-C / Swift Bridge, це приголомшливо, і ви можете перейти до наступного кроку:
Швидкий менеджер пакетів
Час перейти до SwiftPM (або принаймні краще налаштувати ваші Cocoapods).
Справа в тому, що більшість фреймворків із конфігурацією Cocoapods за замовчуванням тягнуть разом із собою безліч речей, які вам не потрібні.
Щоб перевірити це, створіть порожній проект із лише однією залежністю, наприклад PinLayout, і спробуйте написати цей код за допомогою Cocoapods (конфігурація за замовчуванням) та SwiftPM.
import PinLayout
final class TestViewController: UIViewController {
}
Спойлер: Cocoapods буде компілювати цей код, тому що Cocoapods імпортує ВСІЙ ІМПОРТ PinLayout (включаючи UIKit), а SwiftPM не тому, що SwiftPM імпортує рамки атомним шляхом.
Брудний злом
Ви пам'ятаєте, що збірка Xcode є багатопотоковою?
Що ж, ви можете зловживати цим, якщо вам вдасться розділити ваш проект на безліч незалежних фрагментів та імпортувати їх як незалежні рамки до свого проекту. Це знижує з'єднання, і це насправді було першим нами застосованим рішенням, але насправді воно не було дуже ефективним, оскільки ми могли лише скоротити час нарощування до ~ 4-5 м, що НІЧОГО в порівнянні з першим методом.