Открыть список
Как стать автором
Обновить
486,95
Рейтинг
OTUS
Цифровые навыки от ведущих экспертов

Предотвращаем мерж-конфликты с XcodeGen

Блог компании OTUSПрограммированиеРазработка под iOSSwift
Перевод
Автор оригинала: Ricardo Santos

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

И напоследок, предлагаем посмотреть запись вебинара
«Пишем приложение на SwiftUI и Combine».


I - Введение

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

Источник изображения: https://medium.com/@kautilyasave/xcode-merge-conflict-debugging-5904c7e0cc59
Источник изображения: https://medium.com/@kautilyasave/xcode-merge-conflict-debugging-5904c7e0cc59

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

II - Прежде чем мы начнем

1. Знакомство с XcodeGen

yonaskolb/XcodeGen

github.com

XcodeGen — это консольная утилита, написанная на Swift, которая генерирует Xcode-проект на основе вашей структуры папок и спецификации проекта.

Для установки XcodeGen мы будем использовать Brew. Просто запустите в терминале brew install xcodegen (дополнительные параметры установки и инструкции можно найти здесь).

2. Проект

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

В этом руководстве вы узнаете, как шаг за шагом настроить проект, который достаточно прост, чтобы объяснить суть XcodeGen, и в то же время достаточно сложен, чтобы охватить достаточно широкий диапазон вариантов использования.

Пример структуры проекта
Пример структуры проекта

Как мы видим выше, проект содержит:

  • Зависимости фреймворков

  • Сборочные скрипты

III - Настройка

Образцы экранов приложения
Образцы экранов приложения

1. Настраиваем проект

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

Установка проекта (Brew, Carthage, XcodeGen, зависимости…)
Установка проекта (Brew, Carthage, XcodeGen, зависимости…)

2. Создание файла спецификаций проекта XcodeGen

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

Этот файл будет служить спецификацией нашего .xcodeproj
Этот файл будет служить спецификацией нашего .xcodeproj

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 — это путь к файлу спецификации нашего проекта. Если вы выберете другое имя папки/файла, вам также необходимо будет подправить их здесь.

XcodeGen/project.yml: Первый запуск
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: Полная конфигурация (пока)

https://seattle.eater.com/2019/7/2/20679237/july-4th-seattle-where-to-eat-drink-and-watch-the-fireworks
https://seattle.eater.com/2019/7/2/20679237/july-4th-seattle-where-to-eat-drink-and-watch-the-fireworks

На этом этапе после запуска 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».

Теги:iosxcodeswiftswiftuicombine
Хабы: Блог компании OTUS Программирование Разработка под iOS Swift
Всего голосов 8: ↑7 и ↓1 +6
Просмотры1.1K

Комментарии 0

Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

Похожие публикации

Лучшие публикации за сутки

Информация

Дата основания
Местоположение
Россия
Сайт
otus.ru
Численность
51–100 человек
Дата регистрации
Представитель
OTUS

Блог на Хабре