Як зупинити Xcode 11 від зміни CFBundleVersion та CFBundleShortVersionString на $ (CURRENT_PROJECT_VERSION) та $ (MARKETING_VERSION)?


14

Починаючи з версії 11, Xcode встановлює моє CFBundleVersionзначення $(CURRENT_PROJECT_VERSION)та моє CFBundleShortVersionStringзначення $(MARKETING_VERSION)кожного разу, коли я вводя цінність Version або Build у цільові налаштування (вкладка "Загальні").

Фактичні значення версії та збірки, які я ввожу, тепер зберігаються у файлі project.pbxproj. Мені не хочеться і не подобається така поведінка, оскільки я використовую сценарії оболонки для зміни значень під час нарощування.

Я можу вручну встановити правильні значення у файлі Info.plist, але як тільки я зміню номери версій або збірок у цільових налаштуваннях, файл Info.plist знову змінюється на Xcode.

Як я можу зупинити Xcode 11 від цього?

Коли я зміню сценарій збірки, щоб змінити сам файл проекту, Xcode негайно скасує збірку, як тільки файл проекту буде змінено.


Чому ви хочете, щоб Xcode 11 припинив це робити, замість того, щоб змінювати сценарій оболонки, щоб отримати значення?
Мануель

1
@Manuel Я думаю, що змінити пліст за допомогою plistbuddyприємного та чистого, тоді як зміна файлу проекту набагато більш брудно, ненадійно та схильна до неочікуваних змін у форматі файлу.
Містер Zystem

1
Маніпулювання файлом project.pbxproj не є безладним, коли ви розумієте формат файлу. Це просто фільтр стилю Next, який добре задокументований. Ви навіть можете змінити файл з plistbuddy, він сумісний з цим форматом.
Мануель

Я оновив свою відповідь пропозицією для вашого випадку використання.
Мануель

Відповіді:


1

Дорога поки що

Моїм випадком використання було таке:

  1. Я синхронізую версію і будую номери в кількох цілях.
  2. Я синхронізую версію і будую номери з цільовими Settigns.bundle
  3. Я читаю і змінюю номер збірки з сервера CI.

Я використовував для виконання пунктів 1 і 2 як скрипт цільової збірки, а пункт 3 - як власний скрипт на самому CI.

Новий спосіб зберігання версії та побудови в налаштуваннях збірки Xcode спричиняв проблеми зі сценаріями, оскільки вони вже не змогли ефективно змінювати значення. Принаймні читати було можливо.

На жаль, мені не вдалося знайти законний спосіб запобігти збереженню версії та збору номерів Xcode у налаштуваннях проекту, проте мені вдалося створити обхід.

Виявляється, що коли робиться збірка чи архів, використовується значення, записане в Info.plist. Це означає, що значення підміняється протягом часу збирання, що не дозволяє нам змінювати його протягом того ж часу збірки.

Я також намагався модифікувати проект за допомогою xcodeprojcli, однак будь-які зміни проекту спричинили зупинку будь-яких збірок, тому це рішення не працювало.

Врешті-решт, після багатьох різних підходів, які я спробував, я нарешті зумів знайти компроміс, який не порушував нову поведінку 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

Лінії сценарію виконують наступне:

  1. Перейдіть до каталогу, де знаходиться сценарій синхронізації, щоб виконати його
  2. Дозволяє записати журнал під час попередньої дії, інакше будь-який вихід замовчується за замовчуванням
  3. Виконайте сценарій синхронізації, надавши 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, яке повинно мати точно таку ж версію і будувати, як ціль, в яку вона вбудована. Тож я також оновлюю це.


1

Не варто.

Імовірно, є причина, чому така поведінка змінилася. Якщо пізніше функції Xcode будуються на цій поведінці, речі все більше "будуються" вниз по лінії.

Замість того, щоб намагатися згинати Xcode, змініть, як скрипт збірки отримує ці значення:

Як читати поточну версію програми в Xcode 11 зі скриптом

Якщо вам потрібно маніпулювати project.pbxprojфайлом, це фільтр стилю Next, який добре зафіксований. Ви можете використовувати plistbuddyсумісний із цим старим формат. Ви також можете використовувати awkбільше сценаріїв, якщо у вас складніші маніпуляції.

Якщо я розумію ваш випадок використання, ви можете написати сценарій, який отримує найвищі номери версій, awkа потім оновити всі нижчі номери версій, які він може знайти у файлі sed.


значення для друку з, PlistBuddy здається, працює добре, але коли я використовую setкоманду, весь project.pbxproj перетворюється на XML-файл .plist і не може бути прочитаний Xcode. приклад:PlistBuddy -c "Set :objects:$configurationId:buildSettings:CURRENT_PROJECT_VERSION $newProjectVersion" "$projectFile"
Містер Zystem

Залежно від того, чого саме ви хочете досягти, можливо, вам доведеться використовувати комбінацію інструментів
Мануель

Перезапуск Xcode вирішив проблему XML. Als встановив, що при запуску сценарію збірки, який змінює pbxprojфайл, скасується збірка. Отож, боюсь, це насправді не буде працювати.
Містер Зістем

Я оновив своє початкове запитання вищевказаною інформацією.
Містер Зістем

1
Наприклад - мій випадок використання - це синхронізувати версію та будувати на кількох цілях - я хотів би встановити версію та збільшити до першої цілі, яка автоматично оновлюється до всіх інших. Раніше це працювало добре, тому що ви просто змінюєте ресурс. Тепер я не можу змінювати проект під час фази збірки будь-якої цілі, тому що збірка скасовується.
KoCMoHaBTa
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.