Дорога поки що
Моїм випадком використання було таке:
- Я синхронізую версію і будую номери в кількох цілях.
- Я синхронізую версію і будую номери з цільовими
Settigns.bundle
- Я читаю і змінюю номер збірки з сервера CI.
Я використовував для виконання пунктів 1 і 2 як скрипт цільової збірки, а пункт 3 - як власний скрипт на самому CI.
Новий спосіб зберігання версії та побудови в налаштуваннях збірки Xcode спричиняв проблеми зі сценаріями, оскільки вони вже не змогли ефективно змінювати значення. Принаймні читати було можливо.
На жаль, мені не вдалося знайти законний спосіб запобігти збереженню версії та збору номерів Xcode у налаштуваннях проекту, проте мені вдалося створити обхід.
Виявляється, що коли робиться збірка чи архів, використовується значення, записане в Info.plist
. Це означає, що значення підміняється протягом часу збирання, що не дозволяє нам змінювати його протягом того ж часу збірки.
Я також намагався модифікувати проект за допомогою xcodeproj
cli, однак будь-які зміни проекту спричинили зупинку будь-яких збірок, тому це рішення не працювало.
Врешті-решт, після багатьох різних підходів, які я спробував, я нарешті зумів знайти компроміс, який не порушував нову поведінку Xcode.
Коротка відповідь:
Як цільова попередня дія, виконується сценарій, який записує відповідні значення до CFBundleShortVersionString
та CFBundleVersion
в цільовіInfo.plist
Як джерело істини, я використовую параметри збірки Xcode для читання значень MARKETING_VERSION
та CURRENT_PROJECT_VERSION
бажаної цілі.
Таким чином, коли ви змінюєте значення з налаштувань проекту - при наступній збірці / архіві - вони записуються до Info.plist
, дозволяючи будь-якій, якщо ваша існуюча сценарія сценаріїв продовжує працювати.
Детальний відповідь
Єдиний спосіб змінити ресурс під час дії збірки - це використання pre-action
сценарію. Якщо ви спробуєте зробити це за допомогою сценарію збірки - зміни не наберуть чинності одразу і не будуть представлені в кінці збірки / архіву.
Для того, щоб додати дію попереднього збирання - перейдіть до редагування схеми.
Потім розгорніть розділи «Збудувати та архівувати». У розділі Pre-action
Клацніть Provide build and settings from
спадне меню та виберіть джерело істини, з якої ви бажаєте прочитати значення.
Додайте такий сценарій:
# 1)
cd ${PROJECT_DIR}
# 2)
exec > Pruvit-Int.prebuild.sync_project_version_and_build_with_info_plists.log 2>&1
# 3)
./sync_project_version_and_build_with_info_plists.sh $MARKETING_VERSION $CURRENT_PROJECT_VERSION
Лінії сценарію виконують наступне:
- Перейдіть до каталогу, де знаходиться сценарій синхронізації, щоб виконати його
- Дозволяє записати журнал під час попередньої дії, інакше будь-який вихід замовчується за замовчуванням
- Виконайте сценарій синхронізації, надавши
MARKETING_VERSION
іCURRENT_PROJECT_VERSION
Останнім кроком є написання власного сценарію синхронізації, який зчитує значення наданих MARKETING_VERSION
та CURRENT_PROJECT_VERSION
відповідних цілей / с та коли завгодно.
У моєму випадку сценарій такий:
#!/bin/bash
#IMPORTANT - this script must run as pre-action of each target's Build and Archive actions
version_number=$1
build_number=$2
echo "version_number is $version_number"
echo "build_number is $build_number"
#update Pruvit/Info.plist
pruvitInfoPlist="Pruvit/Info.plist"
/usr/libexec/PlistBuddy -c "Set CFBundleShortVersionString $version_number" $pruvitInfoPlist
/usr/libexec/PlistBuddy -c "Set CFBundleVersion $build_number" $pruvitInfoPlist
#update Pruvit/Settings.bundle
settingsPlist="Pruvit/Settings.bundle/Root.plist"
/usr/libexec/PlistBuddy -c "Set PreferenceSpecifiers:0:DefaultValue $version_number" $settingsPlist
/usr/libexec/PlistBuddy -c "Set PreferenceSpecifiers:1:DefaultValue $build_number" $settingsPlist
#update BadgeCounter/Info.plist
badgeCounterInfoPlist="BadgeCounter/Info.plist"
/usr/libexec/PlistBuddy -c "Set CFBundleShortVersionString $version_number" $badgeCounterInfoPlist
/usr/libexec/PlistBuddy -c "Set CFBundleVersion $build_number" $badgeCounterInfoPlist
Я використовую спільний доступ Info.plist
до Settings.bundle
обох цілей програми, тому мені доведеться оновити це один раз.
Також я використовую розширення служби сповіщень BadgeCounter
, яке повинно мати точно таку ж версію і будувати, як ціль, в яку вона вбудована. Тож я також оновлюю це.