Как я могу отобразить версию версии приложения в пакете настроек моего приложения?

91

Я хотел бы включить версию приложения и внутреннюю ревизию, например 1.0.1 (r1243), в пакет настроек моего приложения.

В файле Root.plist есть такой фрагмент ...

     <dict>
        <key>Type</key>
        <string>PSTitleValueSpecifier</string>
        <key>Title</key>
        <string>Version</string>
        <key>Key</key>
        <string>version_preference</string>
        <key>DefaultValue</key>
        <string>VersionValue</string>
        <key>Values</key>
        <array>
            <string>VersionValue</string>
        </array>
        <key>Titles</key>
        <array>
            <string>VersionValue</string>
        </array>
    </dict>

и я хотел бы заменить строку «VersionValue» во время сборки.

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

Панайотис Коррос
источник

Ответы:

69

Есть еще одно решение, которое может быть намного проще, чем любой из предыдущих ответов. Apple включает в себя инструмент командной строки PlistBuddy в большинстве своих установщиков и включил его в Leopard на/usr/libexec/PlistBuddy .

Поскольку вы хотите заменить VersionValue, если у вас есть извлеченное значение версии $newVersion, вы можете использовать эту команду:

/usr/libexec/PlistBuddy -c "Set :VersionValue $newVersion" /path/to/Root.plist

Не нужно возиться с sed или регулярными выражениями, этот подход довольно прост. См. Подробные инструкции на странице руководства. Вы можете использовать PlistBuddy для добавления, удаления или изменения любой записи в списке свойств. Например, мой друг писал в блоге об увеличении номеров сборок в Xcode с помощью PlistBuddy.

Примечание. Если вы укажете только путь к списку, PlistBuddy перейдет в интерактивный режим, поэтому вы можете выполнить несколько команд, прежде чем принять решение о сохранении изменений. Я определенно рекомендую сделать это, прежде чем вставлять это в сценарий сборки.

Куинн Тейлор
источник
20
Мне кажется, мне нужно время, чтобы выяснить, как правильно ссылаться на номер версии в моем списке; в моем случае это оказалось / usr / libexec / PlistBuddy Settings.bundle / Root.plist -c "set PreferenceSpecifiers: 0: DefaultValue $ newversion" - надеюсь, это будет полезно другим людям.
JosephH
Куинн Тейлор, JosephH, благодаря вашим ответам я смог автоматически добавить номер версии моего приложения в Settings.bundle. +1 для вас обоих ;-)
Нико
7
Из настраиваемой фазы сборки «Run Script» мне нужно было включить больше пути к Root.plist: / usr / libexec / PlistBuddy $ {TARGET_BUILD_DIR} / $ {FULL_PRODUCT_NAME} /Settings.bundle/Root.plist -c "set PreferenceSpecifiers: 0: DefaultValue $ newVersion »
Крис Васселли,
2
Для полноты картины вот еще один подход с PListBuddy, который у меня сработал: xcodehelp.blogspot.com/2012/05/...
Koen
самый правильный способ/usr/libexec/PlistBuddy -c "Set :PreferenceSpecifiers:0:DefaultValue ${newVersion}" "${TARGET_BUILD_DIR}/${CONTENTS_FOLDER_PATH}/Settings.bundle/Root.plist"
kambala
66

Решение моего ленивого человека состояло в том, чтобы обновить номер версии из кода моего приложения. У вас может быть значение по умолчанию (или пустое) в Root.plist, а затем где-нибудь в вашем коде запуска:

NSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"];
[[NSUserDefaults standardUserDefaults] setObject:version forKey:@"version_preference"];

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

Вы можете развить идею дальше и обновить, например, счетчик того, сколько раз ваше приложение было запущено, или другую интересную информацию.


источник
9
Это будет работать, кроме случаев, когда пользователь войдет в настройки перед запуском вашего приложения.
Моше
9
@Moshe Верно, но для элегантной обработки вы можете просто указать значение по умолчанию в файле .plist, возможно, что-то вроде «Еще не запущено»
Карлос П.
1
хотя большинство разработчиков, вероятно, устанавливают одно CFBundleShortVersionStringи CFBundleVersionто же значение, CFBundleShortVersionStringна самом деле Apple хочет, чтобы вы считали выпущенную версию именно тем , что вы показываете пользователям. CFBundleVersionпотенциально может быть внутренним номером версии, который вы, вероятно, не должны показывать пользователям (если он отличается).
Nate
3
Я что-то упускаю? Это ТОЧНО то, что я делаю, но значение не меняется. Вы, ребята, не используете свойство Title, которое, как мне кажется, доступно только для чтения?
samson
2
Есть еще одна проблема при обновлении приложения. Пакет настроек будет по-прежнему отображать старую версию сборки, пока обновленное приложение не будет запущено хотя бы один раз.
Legoless
61

Основываясь на ответе @ Quinn, здесь полный процесс и рабочий код, который я использую для этого.

  • Добавьте в приложение пакет настроек. Не переименовывайте его.
  • Откройте Settings.bundle / Root.plist в текстовом редакторе.

Замените содержимое на:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"     "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>PreferenceSpecifiers</key>
    <array>
        <dict>
            <key>Title</key>
            <string>About</string>
            <key>Type</key>
            <string>PSGroupSpecifier</string>
        </dict>
        <dict>
            <key>DefaultValue</key>
            <string>DummyVersion</string>
            <key>Key</key>
            <string>version_preference</string>
            <key>Title</key>
            <string>Version</string>
            <key>Type</key>
            <string>PSTitleValueSpecifier</string>
        </dict>
    </array>
    <key>StringsTable</key>
    <string>Root</string>
</dict>
</plist>
  • Создайте этап сборки Run Script , переместите его после этапа Copy Bundle Resources . Добавьте этот код:

    cd "${BUILT_PRODUCTS_DIR}"
    buildVersion=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "${INFOPLIST_PATH}" )
    /usr/libexec/PlistBuddy -c "Set PreferenceSpecifiers:1:DefaultValue $buildVersion" "${WRAPPER_NAME}/Settings.bundle/Root.plist"
    
  • Замените MyAppName фактическим именем вашего приложения и цифрой 1 после PreferenceSpecifiers, которая будет индексом вашей записи Version в Настройках. В приведенном выше примере Root.plist он имеет индекс 1.

Бен Клейтон
источник
Я думаю, что это лучший способ пойти
Тони
Я попробовал это и вижу, как значение заголовка меняется в моем наборе настроек. Заголовок отображается в InAppSettingsKit, но значение не меняется по сравнению с исходной версией. Заголовок никогда не отображается в приложении "Настройки". Я сдаюсь, и я просто собираюсь открыть диалоговое окно, когда пользователь выбирает «О программе» в меню »
bugloaf
При использовании этого метода параметр не доступен только для чтения. т.е. я могу нажать на номер версии в settings.app, и он доступен для редактирования.
motionpotion
8
Сценарий bash @ ben-Clayton put не сработал для меня, поэтому я переделал его на основе его ответа, вот он:buildVersion=$(/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "${PROJECT_DIR}/${INFOPLIST_FILE}") /usr/libexec/PlistBuddy -c "Set PreferenceSpecifiers:3:DefaultValue $buildVersion" "${SRCROOT}/Settings.bundle/Root.plist"
Луис Аскорбе
1
вы можете использовать ${INFOPLIST_PATH}для информационного пути plist
Tomer Even
23

Использование plist Бена Клейтона https://stackoverflow.com/a/12842530/338986

Добавьте Run scriptследующий фрагмент после Copy Bundle Resources.

version=$(/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "$PROJECT_DIR/$INFOPLIST_FILE")
build=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "$PROJECT_DIR/$INFOPLIST_FILE")
/usr/libexec/PlistBuddy -c "Set PreferenceSpecifiers:1:DefaultValue $version ($build)" "$CODESIGNING_FOLDER_PATH/Settings.bundle/Root.plist"

Добавляя CFBundleVersionв добавлении CFBundleShortVersionString. Он испускает такую ​​версию:

Написав $CODESIGNING_FOLDER_PATH/Settings.bundle/Root.plist вместо одного, вы $SRCROOTполучите некоторые преимущества.

  1. Не изменяет файлы в рабочей копии репозитория.
  2. Вам не нужно указывать путь к Settings.bundlein $SRCROOT. Путь может отличаться.

Тестирование на Xcode 7.3.1

хироши
источник
1
Это лучший ответ IMO, если вы добавите скрипт в раздел Build, Pre-actions схемы проекта. Посмотри на ответ Энди.
Вахид Амири
2
Это работает для меня. Просто не забудьте изменить "DefaultValue" специально для вас. Например, я хотел изменить нижний колонтитул, поэтому я использовал "FooterText". Вам также необходимо изменить номер после «PreferenceSpecifiers», чтобы он соответствовал элементу в списке.
Ричард Уизерспун,
12

На примере здесь , вот сценарий, который я использую для автоматического обновления номера версии пакета настроек:

#! /usr/bin/env python
import os
from AppKit import NSMutableDictionary

settings_file_path = 'Settings.bundle/Root.plist' # the relative path from the project folder to your settings bundle
settings_key = 'version_preference' # the key of your settings version

# these are used for testing only
info_path = '/Users/mrwalker/developer/My_App/Info.plist'
settings_path = '/Users/mrwalker/developer/My_App/Settings.bundle/Root.plist'

# these environment variables are set in the XCode build phase
if 'PRODUCT_SETTINGS_PATH' in os.environ.keys():
    info_path = os.environ.get('PRODUCT_SETTINGS_PATH')

if 'PROJECT_DIR' in os.environ.keys():
    settings_path = os.path.join(os.environ.get('PROJECT_DIR'), settings_file_path)

# reading info.plist file
project_plist = NSMutableDictionary.dictionaryWithContentsOfFile_(info_path)
project_bundle_version = project_plist['CFBundleVersion']

# print 'project_bundle_version: '+project_bundle_version

# reading settings plist
settings_plist = NSMutableDictionary.dictionaryWithContentsOfFile_(settings_path)
  for dictionary in settings_plist['PreferenceSpecifiers']:
    if 'Key' in dictionary and dictionary['Key'] == settings_key:
        dictionary['DefaultValue'] = project_bundle_version

# print repr(settings_plist)
settings_plist.writeToFile_atomically_(settings_path, True)

Вот Root.plist, который у меня есть в Settings.bundle:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>PreferenceSpecifiers</key>
    <array>
        <dict>
            <key>Title</key>
            <string>About</string>
            <key>Type</key>
            <string>PSGroupSpecifier</string>
        </dict>
        <dict>
            <key>DefaultValue</key>
            <string>1.0.0.0</string>
            <key>Key</key>
            <string>version_preference</string>
            <key>Title</key>
            <string>Version</string>
            <key>Type</key>
            <string>PSTitleValueSpecifier</string>
        </dict>
    </array>
    <key>StringsTable</key>
    <string>Root</string>
</dict>
</plist>
mrwalker
источник
Очень полезно - у меня проблемы с запуском PlistBuddy из Python, и я бы никогда не подумал об использовании NSDictionary(и не осознавал, что это дает вам такой легкий доступ к файлам plist)
Дов
Спасибо тебе за это. Одна модификация - в том виде, в котором она есть сейчас, она вносит изменения в исходный код, а не в каталог сборки - это означает, что то, что вы видите на своем устройстве или в симуляторе, всегда будет на одну версию сборки ниже фактической версии сборки. Чтобы исправить это, я изменил ваш скрипт, чтобы сначала перебирать исходный код, а затем и builddir, т.е. settings_path_build = os.path.join (os.environ.get ('TARGET_BUILD_DIR'), settings_file_path_build)
xaphod
... а также добавляю гиташ:gitHash = subprocess.check_output(["git", "rev-parse", "--short", "HEAD"]).rstrip()
xaphod
8

Другие ответы не работают правильно по одной причине: этап сборки сценария запуска не выполняется до тех пор, пока ПОСЛЕ пакета настроек не будет упакован. Итак, если ваша версия Info.plist - 2.0.11, и вы обновите ее до 2.0.12, а затем соберите / заархивируйте свой проект, в пакете настроек все равно будет указано 2.0.11. Если вы откроете пакет настроек Root.plist, вы увидите, что номер версии не обновляется до КОНЕЦ процесса сборки. Вы можете построить проект СНОВА, чтобы правильно обновить пакет настроек, или вместо этого можете добавить сценарий на этап предварительной сборки ...

  • В XCode отредактируйте схему для цели вашего проекта
  • Щелкните стрелку раскрытия на схеме СТРОИТЬ
  • Затем нажмите на пункт «Предварительные действия».
  • Щелкните значок плюса и выберите «Создать действие сценария запуска».
  • Установите значение оболочки на / bin / sh
  • Установите "Предоставить настройки сборки из" для цели вашего проекта.
  • Добавьте свой скрипт в текстовую область. У меня сработал следующий сценарий. Возможно, вам потребуется изменить пути в соответствии с настройками вашего проекта:

    versionString = $ (/ usr / libexec / PlistBuddy -c "Печать CFBundleVersion" "$ {PROJECT_DIR} / $ {INFOPLIST_FILE}")

    / usr / libexec / PlistBuddy "$ SRCROOT / Settings.bundle / Root.plist" -c "set PreferenceSpecifiers: 0: DefaultValue $ versionString"

Это правильно запустит скрипт ДО того, как пакет настроек будет упакован во время процесса сборки / архивирования. Если вы откроете пакет настроек Root.plist и соберете / заархивируете свой проект, вы увидите, что номер версии обновлен в начале процесса сборки, и ваш пакет настроек отобразит правильную версию.

Энди
источник
Спасибо, только ваше решение показывает правильную версию сборки. Остальные решения требовалось построить дважды.
Борис Ю.
Мне все еще требовалась вторая сборка с использованием Xcode 10.0
Патрик,
@Patrick Приложение настроек iOS иногда сохраняет старую информацию. Чтобы увидеть изменения, вам нужно убить и перезапустить приложение «Настройки».
Энди
1
Кстати, я нашел более простой способ добавить этот скрипт: перейдите на вкладку Build Phases цели вашего проекта и щелкните значок «+». Выберите «New Run Script Phase» и добавьте туда код сценария. ЭТО КЛЮЧ: щелкните и перетащите новый сценарий запуска в верхнюю часть списка этапов сборки, в разделе «Целевые зависимости», но перед «Исходные коды компиляции». Он будет вести себя так же, как сценарий предварительной сборки, и его легче найти.
Энди
Спасибо @Andy, ваше решение по добавлению на вкладку Build Phases сработало отлично.
Патрик
7

С Xcode 11.4 вы можете использовать следующие шаги, чтобы отобразить версию приложения в пакете настроек вашего приложения.


Набор $(MARKETING_VERSION)и $(CURRENT_PROJECT_VERSION)переменные

Примечание: если $(MARKETING_VERSION)и $(CURRENT_PROJECT_VERSION)переменные появляются для Bundle version string (short)и Bundle versionключей в Info.plist , вы можете пропустить следующие шаги и перейти к следующему разделу.

  1. Откройте проект Xcode.
  2. Откройте Project Navigator ( cmd1), выберите свой проект, чтобы открыть его настройки, а затем выберите цель приложения.
  3. Выберите вкладку Общие .
  4. в Идентификация » измените содержимое поля « Версия» на какое-то новое значение (например, 0.1.0) и измените содержимое поля « Сборка» на какое-либо новое значение (например 12). Эти 2 изменения будут создавать $(MARKETING_VERSION)и $(CURRENT_PROJECT_VERSION)переменные в Info.plist файл.

Создание и настройка пакета настроек

  1. В навигаторе проекта выберите свой проект.
  2. Выберите Файл > Создать > Файл… ( cmdN).
  3. Выберите вкладку iOS .
  4. Выберите « Пакет настроек» в разделе « Ресурсы », затем нажмите « Далее» и « Создать» .
  5. Выберите Root.plist и откройте его как исходный код. Замените его содержимое приведенным ниже кодом:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>PreferenceSpecifiers</key>
    <array>
        <dict>
            <key>DefaultValue</key>
            <string></string>
            <key>Key</key>
            <string>version_preference</string>
            <key>Title</key>
            <string>Version</string>
            <key>Type</key>
            <string>PSTitleValueSpecifier</string>
        </dict>
    </array>
    <key>StringsTable</key>
    <string>Root</string>
</dict>
</plist>

Добавить сценарий запуска

  1. В навигаторе проекта выберите свой проект.
  2. Выберите цель приложения.
  3. Выберите вкладку Build Phases .
  4. Нажмите + > New Run Script Phase .
  5. Перетащите новую фазу куда-нибудь выше раздела Copy Bundle Resources . Таким образом, сценарий будет выполнен перед компиляцией приложения.
  6. Откройте только что добавленную фазу запуска сценария и добавьте следующий сценарий:
version="$MARKETING_VERSION"
build="$CURRENT_PROJECT_VERSION"
/usr/libexec/PlistBuddy -c "Set PreferenceSpecifiers:0:DefaultValue $version ($build)" "${SRCROOT}/Settings.bundle/Root.plist"

Запустить приложение

  1. Запустите продукт (cmdR ) на устройстве или симуляторе.
  2. На устройстве или симуляторе после запуска приложения откройте приложение « Настройки» и выберите свое приложение в списке сторонних приложений. Версия приложения должна отображаться, как показано ниже:


Источники

Иману Пети
источник
Это вызывает у меня ошибкуSet: Entry, "PreferenceSpecifiers:0:DefaultValue", Does Not Exist
Jordan H
2
Это сработало для меня:/usr/libexec/PlistBuddy "$SRCROOT/AppName/Settings.bundle/Root.plist" -c "set PreferenceSpecifiers:0:DefaultValue $version"
Jordan H
Спасибо. Это какой мир для меня. Но мой был назван Settings-Watch.bundle и удален($build)
Kurt Lane
3

Мне удалось сделать то, что я хотел, используя проект с открытым исходным кодом pListcompiler ( http://sourceforge.net/projects/plistcompiler ).

  1. Используя этот компилятор, вы можете записать файл свойств в файл .plc, используя следующий формат:

    plist {
        dictionary {
            key "StringsTable" value string "Root"
            key "PreferenceSpecifiers" value array [
                dictionary {
                    key "Type" value string "PSGroupSpecifier"
                    key "Title" value string "AboutSection"
                }
                dictionary {
                    key "Type" value string "PSTitleValueSpecifier"
                    key "Title" value string "Version"
                    key "Key" value string "version"
                    key "DefaultValue" value string "VersionValue"
                    key "Values" value array [
                        string "VersionValue"
                    ]
                    key "Titles" value array [
                        string "r" kRevisionNumber
                    ]
                }
            ]
        }
    }
    
  2. У меня была фаза сборки настраиваемого сценария запуска, которая извлекала мою версию репозитория в файл .h, как описано здесь Брэдом-Ларсоном .

  3. Файл plc может содержать директивы препроцессора, такие как #define, #message, #if, #elif, #include, #warning, #ifdef, #else, #pragma, #error, #ifndef, #endif, переменные среды xcode. Поэтому я смог сослаться на переменную kRevisionNumber, добавив следующую директиву

    #include "Revision.h"
    
  4. Я также добавил настраиваемую фазу сборки скрипта в мою цель xcode, чтобы запускать plcompiler каждый раз, когда проект находится в стадии сборки.

    /usr/local/plistcompiler0.6/plcompile -dest Settings.bundle -o Root.plist Settings.plc
    

Вот и все!

Панайотис Коррос
источник
Звучит как большая работа, чтобы просто заменить одно значение в файле plist ... Концептуально иметь возможность получить доступ к переменной при построении списка plist, но гораздо проще использовать сборку инструмента для файла plist. Я описываю PlistBuddy в своем ответе - попробуйте!
Куинн Тейлор,
3

Мой рабочий пример, основанный на ответе @Ben Clayton и комментариях @Luis Ascorbe и @Vahid Amiri:

Примечание. Этот подход изменяет файл Settings.bundle / Root.plist в рабочей копии репозитория.

  1. Добавьте пакет настроек в корень вашего проекта. Не переименовывать это

  2. Откройте Settings.bundle / Root.plist как SourceCode

    Замените содержимое на:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
        <key>PreferenceSpecifiers</key>
        <array>
            <dict>
                <key>DefaultValue</key>
                <string></string>
                <key>Key</key>
                <string>version_preference</string>
                <key>Title</key>
                <string>Version</string>
                <key>Type</key>
                <string>PSTitleValueSpecifier</string>
            </dict>
        </array>
        <key>StringsTable</key>
        <string>Root</string>
    </dict>
    </plist>
    
  3. Добавьте следующий скрипт в раздел Сборка, Предварительные действия схемы проекта (цели)

    version=$(/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "$PROJECT_DIR/$INFOPLIST_FILE")
    build=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "$PROJECT_DIR/$INFOPLIST_FILE")
    
    /usr/libexec/PlistBuddy -c "Set PreferenceSpecifiers:0:DefaultValue $version ($build)" "${SRCROOT}/Settings.bundle/Root.plist"
    
  4. Построить и запустить текущую схему

Питер Крейнц
источник
2

Вышеупомянутые ответы не сработали для меня, поэтому я создал свой собственный скрипт.

Это динамически обновляет запись из Root.plist

Используйте сценарий запуска ниже. Будет работать точно проверено в xcode 10.3.

"var buildVersion" - версия, которая будет отображаться в заголовке.

И имя идентификатора "var version" ниже для заголовка в settings.bundle Root.plist

cd "${BUILT_PRODUCTS_DIR}"

#set version name to your title identifier's string from settings.bundle
var version = "Version"

#this will be the text displayed in title
longVersion=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "${INFOPLIST_PATH}")
shortVersion=$(/usr/libexec/PlistBuddy -c "Print :CFBundleShortVersionString" ${TARGET_BUILD_DIR}/${INFOPLIST_PATH})
buildVersion="$shortVersion.$longVersion"

path="${WRAPPER_NAME}/Settings.bundle/Root.plist"

settingsCnt=`/usr/libexec/PlistBuddy -c "Print PreferenceSpecifiers:" ${path} | grep "Dict"|wc -l`

for (( idx=0; idx<$settingsCnt; idx++ ))
do
#echo "Welcome $idx times"
val=`/usr/libexec/PlistBuddy -c "Print PreferenceSpecifiers:${idx}:Key" ${path}`
#echo $val

#if ( "$val" == "Version" )
if [ $val == "Version" ]
then
#echo "the index of the entry whose 'Key' is 'version' is $idx."

# now set it
/usr/libexec/PlistBuddy -c "Set PreferenceSpecifiers:${idx}:DefaultValue $buildVersion" $path

# just to be sure that it worked
ver=`/usr/libexec/PlistBuddy -c "Print PreferenceSpecifiers:${idx}:DefaultValue" $path`
#echo 'PreferenceSpecifiers:$idx:DefaultValue set to: ' $ver

fi

done

Пример записи в Root.plist

    <dict>
        <key>Type</key>
        <string>PSTitleValueSpecifier</string>
        <key>Title</key>
        <string>Version</string>
        <key>DefaultValue</key>
        <string>We Rock</string>
        <key>Key</key>
        <string>Version</string>
    </dict>

Рабочий образец записи Root.plist

dheeraj_jha
источник
1

Я считаю, что вы можете сделать это, используя способ, аналогичный тому, что я описываю в этом ответе (на основе этого сообщения ).

Во-первых, вы можете сделать VersionValue переменной в Xcode, переименовав ее в $ {VERSIONVALUE}. Создайте файл с именем versionvalue.xcconfig и добавьте его в свой проект. Перейдите к цели вашего приложения и перейдите к настройкам сборки для этой цели. Я считаю, что вам нужно добавить VERSIONVALUE в качестве пользовательского параметра сборки. В правом нижнем углу этого окна измените значение «На основе» на «значение версии».

Наконец, перейдите к своей цели и создайте этап сборки Run Script. Проверьте этап «Выполнить сценарий» и вставьте свой сценарий в текстовое поле «Сценарий». Например, мой сценарий для пометки моего параметра BUILD_NUMBER текущей сборкой Subversion выглядит следующим образом:

REV=`/usr/bin/svnversion -nc ${PROJECT_DIR} | /usr/bin/sed -e 's/^[^:]*://;s/[A-Za-z]//'`
echo "BUILD_NUMBER = $REV" > ${PROJECT_DIR}/buildnumber.xcconfig

Это должно помочь заменить переменную при изменении этих значений в вашем проекте.

Брэд Ларсон
источник
Это работает, если я хочу встроить номер версии в файл Info.plist. Но я не могу заставить его работать для других файлов plist, например файла Root.plist, который находится в Settings.bundle. Есть ли параметр сборки, который я могу использовать, чтобы включить это?
Панайотис Коррос
0

Для меня это было самым простым решением:

Добавьте новую фазу сборки скрипта перед шагом Копировать ресурсы пакета

Оболочка: /usr/bin/env python

Содержание:

#! /usr/bin/env python
import os
from AppKit import NSMutableDictionary

# Key to replace
settings_key = 'version_preference' # the key of your settings version

# File path
settings_path = os.environ.get('SRCROOT') + "/TheBeautifulNameOfYourOwnApp/Settings.bundle/Root.plist"

# Composing version string
version_string = os.environ.get('MARKETING_VERSION') + " (" + os.environ.get('CURRENT_PROJECT_VERSION') + ")"

# Reading settings plist
settings_plist = NSMutableDictionary.dictionaryWithContentsOfFile_(settings_path)
for dictionary in settings_plist['PreferenceSpecifiers']:
    if 'Key' in dictionary and dictionary['Key'] == settings_key:
        dictionary['DefaultValue'] = version_string

# Save new settings
settings_plist.writeToFile_atomically_(settings_path, True)
gklka
источник