Привет, Хабр! В преддверии старта курса «iOS Developer. Professional» подготовили для вас традиционный перевод полезного материала. Также приглашаем желающих на онлайн-встречу с преподавателем курса, на которой можно задать преподавателю интересующие вас вопросы об обучении.
И напоследок, предлагаем посмотреть запись вебинара «Пишем приложение на SwiftUI и Combine».

I — Введение
В этой статье мы рассмотрим решение для мгновенного разрешения мерж-конфликтов в файле .xcodeproj, что является одной из самых трудоемких проблем, с которыми сегодня сталкиваются команды iOS и macOS разработчиков.

К концу этой статьи у вас будет рабочая среда, обеспечивающая бесконфликтное слияние.

II — Прежде чем мы начнем
1. Знакомство с XcodeGen
yonaskolb/XcodeGen
XcodeGen — это консольная утилита, написанная на Swift, которая генерирует Xcode-проект на основе вашей структуры папок и спецификации проекта.
Для установки XcodeGen мы будем использовать Brew. Просто запустите в терминале brew install xcodegen (дополнительные параметры установки и инструкции можно найти здесь).

2. Проект
В наше время большинство проектов не так уж и просты. У них есть несколько конфигураций, зависимостей (предоставленных третьими лицами или разработанных как часть проекта), скриптов, которые запускаются как часть процесса сборки, CI и т. д.
В этом руководстве вы узнаете, как шаг за шагом настроить проект, который достаточно прост, чтобы объяснить суть XcodeGen, и в то же время достаточно сложен, чтобы охватить достаточно широкий диапазон вариантов использования.

Как мы видим выше, проект содержит:
-
Зависимости фреймворков
-
Carthage-зависимости
-
Схемы и конфигурации
-
Сборочные скрипты

III — Настройка

1. Настраиваем проект
Проект (sample project), который мы будем использовать в этом туториале, имеет carthage-зависимости. Просто запустите makeProject.sh в терминале. Это настроит проект со всеми его зависимостями, и мы сможем начать туториал.


2. Создание файла спецификаций проекта XcodeGen
В корневом каталоге проекта создайте папку с именем XcodeGen (имя папки необязательно должно быть таким) с файлом названным project.yml (это имя файла тоже опционально).

XcodeGen/project.yml: Первоначальная настройка:
name: GoodToGo options: bundleIdPrefix: com.GoodToGo xcodeVersion: '12.0.1' deploymentTarget: '12.0' groupSortPosition: top generateEmptyDirectories: true findCarthageFrameworks: true minimumXcodeGenVersion: '2.18.0'
Во время нашей первоначальной настройки для файла .xcodeproj мы выбираем имя — GoodToGo — , префикс пакета — com.GoodToGo — , версию Xcode, целевую платформу развертывания…

3. Первый запуск XcodeGen
Используя описанную выше конфигурацию, мы можем создать наш новый проект, запустив xcodegen -s ./XcodeGen/project.yml -p ./ в терминале.
Обратите внимание, что ./XcodeGen/project.yml — это путь к файлу спецификации нашего проекта. Если вы выберете другое имя папки/файла, вам также необходимо будет подправить их здесь.

Зеленое сообщение говорит о том, что проект был создан. Ура, мы успешно создали наш проект!
Теперь давайте откроем его и посмотрим, как он выглядит:

Не то, что мы ожидали… Отсутствуют все наши схемы, все фреймворки, вообще все. Они отсутствуют, потому что мы не определили их в нашем файле project.yml.

4. Добавление конфигураций и основного таргета проекта
XcodeGen/project.yml: Добавление конфигураций. Просто добавьте это в свой файл project.yml:
configs: Debug.Dev: debug Debug.Prod: debug Release: release targets: GoodToGo: type: application platform: iOS deploymentTarget: 12.0 settings: base: MARKETING_VERSION: 1.0 sources: - path: ../GoodToGo
По сути, мы создаем 3 конфигурации — Debug.Dev, Debug.Prod и Release, и заявляем что основной таргет нашего приложения будет называться GoodToGo, с целевой платформой iOS 12 (минимальная версия), а файлы исходного кода находятся в папке GoodToGo.
Папка должна существовать в системных папках, иначе у вас будет следующая ошибка:
Spec validation error: Target “GoodToGo” has a missing source directory “/Users/ricardosantos/Desktop/GitHub/RJPS_Articles/7/sourcecode/THE_FOLDER_THAT_DOES_NOT_EXISTS_NAME”

Попробуйте снова с нашей обновленной конфигурацией (предыдущее изображение) и…

… теперь у нас есть (предыдущее изображение) схемы, конфигурации и таргет приложения!

5. Добавление фреймворков
Следующее, что нам нужно сделать, — это добавить зависимости наших фреймворков. Для каждого из них нам нужно выбрать платформу, тип, таргет и другие параметры.
Мы знаем с самого начала, что обычно все фреймворки имеют одни и те же настройки, поэтому мы создадим шаблон и назовем его Framework.
Ниже вы можете увидеть простой шаблон, на который мы будем ссылаться в нашем основном файле project.yml, а затем и там, где это необходимо.
XcodeGen/project.yml: Создание шаблона:
targetTemplates: Framework: type: framework platform: iOS deploymentTarget: 11.0 settings: base: MARKETING_VERSION: 1.0
В этом шаблоне указано, что все целевые объекты будут иметь следующие условия:
-
тип framework,
-
платформа iOS,
-
версию 1.0,
-
целевую платформу для развертывания, равную или выше, iOS 11.0.
В нашем образце проекта у нас были следующие зависимости фреймворков (смотрите ниже).

Мы добавим парочку для проверки: AppTheme и AppResources.
Начиная с нашего файла project.yml в разделе таргетов мы добавим 2 новые записи (AppTheme и AppResources). Для этих таргетов мы должны определить исходную папку и имя шаблона, как объяснялось в предыдущем шаге.
AppTheme: templates: - Framework sources: - path: ../AppTheme AppResources: templates: - Framework sources: - path: ../AppResources
XcodeGen/project.yml: Добавление таргетов с помощью шаблона

Попробуем еще раз с нашей обновленной конфигурацией (предыдущее изображение) и…

… теперь у нас есть основной таргет нашего приложения и 2 зависимости, которые мы только что добавили в наш файл спецификации.
Небольшое резюме: раздел таргетов в нашем project.yml должен выглядеть так:
targets: GoodToGo: type: application platform: iOS deploymentTarget: 12.0 settings: base: MARKETING_VERSION: 1.0 sources: - path: ../GoodToGo AppTheme: templates: - Framework sources: - path: ../AppTheme AppResources: templates: - Framework sources: - path: ../AppResources
Для завершения настройки нам нужно добавить остальные фреймворки, после чего наш файл project.yml должен выглядеть следующим образом:
name: GoodToGo ## options section ## options: bundleIdPrefix: com.GoodToGo xcodeVersion: '12.0.1' deploymentTarget: '12.0' groupSortPosition: top generateEmptyDirectories: true findCarthageFrameworks: true minimumXcodeGenVersion: '2.18.0' ## configs section ## configs: Debug.Dev: debug Debug.Prod: debug Release: release ## targetTemplates section ## targetTemplates: Framework: type: framework platform: iOS deploymentTarget: 11.0 settings: base: MARKETING_VERSION: 1.0 ## targets section ## targets: GoodToGo: type: application platform: iOS deploymentTarget: 11.0 settings: base: MARKETING_VERSION: 1.0 sources: - path: ../GoodToGo AppTheme: templates: - Framework sources: - path: ../AppTheme AppResources: templates: - Framework sources: - path: ../AppResources AppConstants: templates: - Framework sources: - path: ../AppConstants Core: templates: - Framework sources: - path: ../Core Core.GalleryApp: templates: - Framework sources: - path: ../Core.GalleryApp Domain: templates: - Framework sources: - path: ../Domain Core.GalleryApp: templates: - Framework sources: - path: ../Core.GalleryApp Designables: templates: - Framework sources: - path: ../Designables DevTools: templates: - Framework sources: - path: ../DevTools Extensions: templates: - Framework sources: - path: ../Extensions Factory: templates: - Framework sources: - path: ../Factory PointFreeFunctions: templates: - Framework sources: - path: ../PointFreeFunctions Repositories: templates: - Framework sources: - path: ../Repositories Repositories.WebAPI: templates: - Framework sources: - path: ../Repositories.WebAPI UIBase: templates: - Framework sources: - path: ../UIBase Test.GoodToGo: type: bundle.unit-test platform: iOS sources: - path: ../Test.GoodToGo scheme: {}
XcodeGen/project.yml: Полная конфигурация (пока)

На этом этапе после запуска XcodeGen у нас должен получиться проект со всеми фреймворками!

Настраивая подобные вещи, мы всегда натыкаемся на некоторые неровности на дороге. Одна из них — пропавшая ссылка на файл .plist. Это можно исправить 2-мя способами: первый заключается в указании в project.yml пути к файлу .plist, а второй вариант заключается в переименовании GoodToGo-info.plist в Info.plist.

6. Подтягиваем зависимости фреймворков
На этом этапе у нас есть базовая конфигурация проекта, схемы и наши фреймворки. Пришло время подтянуть наши зависимости и успешно скомпилировать наш проект.
Например, мы заметили, что Domain зависит от RxCocoa и RxSwift, а эти зависимости разрешаются с помощью carthage.

Во-первых, нам нужно найти таргет Domain в нашем файле project.yml…XcodeGen/project.yml: Таргет Domain без зависимостей:
Domain: templates: - Framework sources: - path: ../Domain
… а затем добавить недостающие (carthage) зависимости. Вот так просто!XcodeGen / project.yml: Таргет Domain с зависимостями:
Domain: templates: - Framework sources: - path: ../Domain dependencies: - carthage: RxSwift - carthage: RxCocoa
Для добавления зависимостей у нас есть несколько вариантов, но в нашем проекте мы используем всего 3:
-
Добавить carthage-зависимость,
-
Добавить зависимость проекта с привязкой (link: true),
-
Добавить зависимость проекта без привязки (link: false).
XcodeGen/project.yml: Пример трех вариантов зависимостей (carthage, с привязкой и без):
dependencies: - carthage: RxSwift - carthage: RxCocoa - target: BaseUI link: false - target: DevTools link: true - target: UICarTrack link: false
Вы можете узнать больше о добавлении зависимостей здесь.
Пришло время подтянуть все зависимости в нашем проекте, и в целом все готово! «В целом» — это просто способ сказать, что эта задача, вероятно, является наиболее трудоемкой, т.к. она состоит из цикла:
-
1. Создание
.xcodeprojectи его открытие,
-
2. Компиляция проекта и определение недостающих зависимостей,
-
3. Добавление недостающих зависимостей в
project.yml,
-
4. Возвращение к шагу 1.

7. Дополнительно: скрипты сборки
В исходном проекте у нас было несколько скриптов сборки (как мы видим на изображении ниже):

Мы можем добиться того же результата, добавив чайлда postCompileScript.
GoodToGo: type: application platform: iOS deploymentTarget: 12.0 settings: base: MARKETING_VERSION: 1.0 sources: - path: ../GoodToGo dependencies: ... postCompileScripts: - script: | if which swiftlint >/dev/null; then swiftlint else echo "warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint" fi name: Run SwiftLint

8. Дополнительно: папка Documents
Мы также можем добавить папку Documents. Файлы внутри этой папки не будут добавлены ни в какой таргет и, следовательно, не будут обрабатываться как часть сборки. Просто добавьте путь к папке с документами в раздел fileGroups (подробнее о fileGroups здесь).
fileGroups: - ../Documents


IV — Резюме
-
Мы создали базовый файл
project.ymlи использовали XcodeGen, чтобы он сгенерировал наш проект (подробнее здесь)
-
Мы добавили некоторые конфигурации проекта (подробнее здесь)
-
Мы добавили все необходимые нам таргеты
-
Мы подтянули зависимости наших таргетов (подробнее здесь)
-
Мы добавили папку с документами (подробнее здесь)
-
Мы добавили скрипты сборки
1. Проблемы, с которыми вы можете столкнуться при настройке проекта в первый раз: Потерянные файлы

Иногда такое может случится с каждым из нас. При удалении некоторых старых/устаревших файлов из проекта мы выбираем опцию Remove Reference вместо перемещения файла в корзину. Эти файлы появятся снова, когда мы будем использовать XcodeGen (помните, что все файлы внутри папки будут добавлены в таргет). Если вы действительно хотите сохранить эти файлы, поместите их в папку Documents.

2. Проблемы, с которыми вы можете столкнуться при настройке проекта в первый раз: Разные файлы внутри папок
Иногда внутри папок наших таргетов лежат разные файлы. Опять же, помните, что все файлы внутри папки таргета будут добавлены в таргет и, следовательно, скомпилированы. Вы можете избежать этого, поместив эти файлы в папку Documents.

V — Ссылки
-
Проект перед преобразованием можно найти здесь.
-
Код финального проекта можно найти здесь.
-
Финальный project.yml можно найти здесь.
-
Больше примеров подобных проектов можно найти здесь.
Узнать подробнее о курсе «iOS Developer. Professional».
Смотреть запись вебинара «Пишем приложение на SwiftUI и Combine».
ссылка на оригинал статьи https://habr.com/ru/company/otus/blog/543260/
Добавить комментарий