У нас была такая же проблема, и мы ее исправили. Дважды.
Инкрементная сборка (та же машина сборки):
до: ~ 10 м после: ~ 35 с
КАК?
Давайте сначала начнем с нашего опыта. У нас был огромный проект Swift / Obj- C, и это было главной заботой: время сборки было медленным, и вам пришлось создавать новый проект для реализации новой функции (буквально). Бонусные баллы за неработающую подсветку синтаксиса.
Теория
Чтобы действительно это исправить, вы должны по-настоящему понять , как работает система сборки. Например, давайте попробуем этот фрагмент кода:
import FacebookSDK
import RxSwift
import PinLayout
и представим, что вы используете все эти операции импорта в своем файле. А также этот файл зависит от другого файла, который зависит от других библиотек, которые, в свою очередь, используют другие библиотеки et c.
Таким образом, для компиляции вашего файла XCode должен скомпилировать каждую библиотеку , которую вы упомянули, и каждый файл , от которого это зависит, так что если вы измените один из "основных" файлов Xcode нужно перестроить буквально весь проект.
![Dependency tree](https://i.stack.imgur.com/c0ZSv.jpg)
Xcode build многопоточный , но состоит из множества однопоточных деревья .
Итак, на первом шаге каждой инкрементальной сборки Xcode решает, какие файлы необходимо перекомпилировать, и создает дерево AST . Если вы измените файл, который действует как « зависящий » для других файлов, то каждый другой файл, который действует как « зависимый », должен быть перекомпилирован.
![Coupling](https://i.stack.imgur.com/R8GlS.jpg)
Итак, первый совет: нижняя муфта . Части вашего проекта должны быть независимы друг от друга.
Мост Obj-C / Swift
Проблема с этими деревьями, если вы используете мост Obj-C / Swift, Xcode должен go через больше фаз, чем обычно:
Идеальный мир:
- Builds Obj- C код
- Build Swift код
![Swift/Obj-C bridge](https://i.stack.imgur.com/UbM6Z.jpg)
Мост Obj-C / Swift:
- [REPEATABLE STEP] Построить код Swift, необходимый для компиляции Obj- C код
- [REPEATABLE STEP] Build Obj- C код, необходимый для компиляции кода Swift
- Повторяйте 1 и 2 до тех пор, пока у вас не останется только надежный Swift & Obj- C оставленный код
- Build Obj- C код
- Build Swift код
![Obj-C/Swift bridge](https://i.stack.imgur.com/rg52p.jpg)
Так что если Вы меняете что-то с шага 1 или 2, у вас в основном проблемы. Лучшее решение - минимизировать Obj-C / Swift Bridge (и удалить его из вашего проекта).
Если у вас нет Obj-C / Swift Bridge, это здорово, и вы хороши для go до следующего шага:
Диспетчер пакетов Swift
Время перейти на SwiftPM (или, по крайней мере, лучше настроить ваши Cocoapods).
Дело в том, что большинство фреймворков по умолчанию Конфигурация Cocoapods тащит за собой множество вещей, которые вам не нужны.
Чтобы проверить это, создайте пустой проект с одной зависимостью, такой как PinLayout, например, и попробуйте написать этот код с помощью Cocoapods (конфигурация по умолчанию) и SwiftPM.
import PinLayout
final class TestViewController: UIViewController {
}
Spoiler: Cocoapods скомпилируйте этот код, потому что Cocoapods будет импортировать КАЖДЫЙ ИМПОРТ PinLayout (включая UIKit), а SwiftPM не будет, потому что SwiftPM импортирует фреймворки атомарно.
Dirty hack
Помните, сборка Xcode является многопоточной?
Что ж, вы можете злоупотребить этим, если вам удастся разделить ваш проект на множество независимых частей и импортировать все из них как независимые фреймворки в ваш проект. Это снижает связь, и это было фактически первое решение, которое мы использовали, но на самом деле оно было не очень эффективным, потому что мы могли только сократить время инкрементной сборки до ~ 4-5 м, что НИЧЕГО по сравнению с первым методом.