как заставить Xcode перестроить информацию.plist файл в моем проекте каждый раз, когда я строю проект?

по-видимому, файл кэшируется, поэтому он создается только при его изменении. У меня есть переменные среды, установленные для увеличения моего номера версии, хотя и такие, и обновляют их независимо от plist (на самом деле в настройках сборки проекта). Есть ли скрипт, который я могу использовать в качестве этапа сборки скрипта, который заставит информацию.plist для обновления? Какой-нибудь другой удобный способ?

10 ответов


выберите "изменить схему", затем выберите "построить" из элемента управления слева.

затем добавьте шаг предварительных действий, убедитесь, что рассматриваемая схема выбрана в раскрывающемся списке "предоставить настройки сборки из", а затем добавьте это в окно редактирования ниже:

rm "${CONFIGURATION_BUILD_DIR}/${INFOPLIST_PATH}"

это удалит кэшированную версию Info.plist, заставляя XCode перестраивать его каждый раз, когда вы нажимаете build.


Я тоже автоматизировал настройку номеров версий. Я создал Выполнить Скрипт Этап Сборки. Ключ состоит в том, чтобы обновить целевую копию каталога сборки информации.plist в каталоге не построить один. Вам также необходимо иметь сценарий запуска после фазы копирования пакета. Это нормально редактировать bundle файл непосредственно потому, что перед подписанием кода. Вы не хотите создавать файл, который изобретает колесо.

вот мой сценарий:

# ---------------------------- IMPORTANT ----------------------------
# You must set GITHash to something like 'Set by build script' in the file
# file '<Project Name>-Info.plist' in the 'Supporting Files' group
# -------------------------------------------------------------------
#
# Get the version number from the tag in git and the number of commits as the build number
#
appVersion=$(git describe --long | cut -f 1 -d "-") 
appBuild=$(git describe --long | cut -f 2 -d "-") 
gitHash=$(git describe --long | cut -f 3 -d "-")
echo "From GIT Version = $appVersion Build = $appBuild"

#
# Set the version info in plist file
#
/usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString $appVersion" "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}"
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $appBuild" "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}"
/usr/libexec/PlistBuddy -c "Set :GITHash $gitHash" "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}"
echo "Updated ${TARGET_BUILD_DIR}/${INFOPLIST_PATH}"

к твоему сведению!--4--> Я также автоматически устанавливаю версию и строю на вкладке About со следующим кодом

NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary];
NSString *appDisplayName = infoDictionary[@"CFBundleDisplayName"];
NSString *majorVersion = infoDictionary[@"CFBundleShortVersionString"];
NSString *minorVersion = infoDictionary[@"CFBundleVersion"];

self.appDescription.text = [NSString stringWithFormat:@"Dirty Dog Software\n%@\nVersion: %@(%@)",
                       appDisplayName, majorVersion, minorVersion];                           

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

$ touch Info.plist

один из способов сделать это было бы иметь этап сборки сценария запуска для генерации Info.plist с , а потом rm Info.plist после создания пакета. Идея из комментария Дэйв Делонг опубликовано в его блоге здесь.

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


в Xcode 4 Вы можете использовать действие предварительной сборки, чтобы коснуться info plist.

Примечание: это не то же самое как запустить скрипт этап построения. Действие предварительной сборки происходит до того, как Xcode проверяет info plist, фаза сборки сценария запуска происходит после того, как Xcode уже проверил info plist (поэтому он работает только каждый раз).

  1. перейти к редактированию схемы > сборка > предварительные действия
  2. Нажмите кнопку " + "и выберите" новый скрипт запуска Действие"
  3. выберите цель в раскрывающемся списке" предоставить настройки сборки из"
  4. добавить touch "${SRCROOT}/${INFOPLIST_FILE}" в поле скрипт

есть опция на вкладке " сборка "окна Get Info цели, вниз в" Упаковка "с надписью" информация о предварительной обработке.файл plist", который вы можете проверить. Я считаю, что будет обновлять файл каждую сборку.


работа с Xcode 8.3.2

вдохновленный ответом @LeeH от 2013 я придумал два решения для меня, чтобы восстановить информацию.файл plist.

Решение 1: Самый простой и элегантный

самое простое решение-заставить Xcode читать ваши пользовательские переменные трогательно ваши задачи Info.plist.

добавить этап сборки, см. скриншот ниже (первоначально скриншот для решение 2), и просто добавить эта строка:

touch $INFOPLIST_FILE

вот и все! Теперь Xcode должен заставить перезагрузить пользовательские переменные в .

это решение такое же, как @lukelutman предложил, но с использованием фазы сборки. Предварительный сценарий не сработал.

решение 2: более сложный и хакерский

другое решение-удалить кэшированные Info.plist в Реж.

я написал этот супер простой маленький bash скрипт

#!/bin/bash
info_plist="$CONFIGURATION_BUILD_DIR/$PRODUCT_NAME.app/Info.plist"
echo "Removing Info.plist from build dir in order to force rebuild of it and reading of correct xcconfig variables, plist path $info_plist"
rm "$info_plist"

затем я сохранил его и вызвал его из этапов сборки для цели. Я назвал это первым этапом сборки.

enter image description here

Справочная информация:

у меня три разные конфигурации:Config, Alpha, AppStore и я использую универсальные ссылки, Push-уведомления и другой персонал, который требует использования файла прав. Но я не хотел иметь три файла прав, по одному для каждого конфиг.

мой проект уже сильно зависит от конфигурационных файлов (.xcconfig). Я фактически настроил файл права (MyAppsProductName.entitlements) С использованием пользовательских переменных конфигурации.

но я хотел прочитать ту же среду выполнения переменных конфигурации, я решил, что смогу это сделать, если они будут добавлены к моей целевой информации.файл plist. И это сработало!

но я заметил, что когда я изменил значения в моем , потом Info.plist файл не изменил значение. Я заметил, что если я выступал чистая сборка, затем значения в Info.plist получил обновления в соответствии со значениями внутри . Xcode действительно кэширует .

таким образом, эти решения выше устраняет эту проблему. Надеюсь, это поможет! :)

Обсуждение

я понятия не имею, если решение 2 имеет никаких преимуществ перед Решение 1... Наверное, нет? Любой вход кого-нибудь?


убедитесь, что вы также обновили представление plist.
При просмотре plist в Xcode просто нажмите треугольник раскрытия рядом с корневым элементом в plist (Information Property List). А затем щелкните его еще раз, чтобы развернуть.
Вы увидите, что значения были обновлены. Я запускал аналогичный сценарий и думал, что он работает только периодически, пока не понял, что представление plist просто не освежает.


другой подход-создать "агрегатную" цель, которая имеет только фазу сборки. Используйте это, чтобы коснуться информации.plist файл. Сделайте эту цель зависимостью от цели, которая создает ваше приложение.

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


для тех, кто изо всех сил пытался получить проект для автоматического управления версиями, я создал проект macOS GitHub это демонстрирует, как реализовать его очень простым и простым способом, благодаря идеям @GayleDDS и Даниэля Фаррелли и его блога о версионировании и некоторой реализации моего собственного. Я думаю, вы можете перевести его в ваши проекты на других платформах без каких-либо хлопот.

вот небольшое руководство о том, как вы можете использовать ее в ваших проектах (Xcode 8).

  1. чтобы уменьшить вероятность того, что вы получите это неправильно, убедитесь, что вы уже добавили все свои цели в свой проект заранее.
  2. перейдите в меню Файл > Новый Файл... а затем прокрутите вниз и выберите Настройки
  3. имя BuildNumber не забудьте добавьте этот файл конфигурации ко всем целям вы хотите сохранить в синхронизации; сделать это, нажав на соответствующую флажки перед сохранением этого файла
  4. вы должны увидеть файл с именем BuildNumber.xcconfig показать в вашем проекте
  5. добавить в этот файл следующий текст: CURRENT_PROJECT_VERSION = 1. Если хотите, можете начать с другого номера. Это будет ваш номер сборки, который будет увеличиваться каждый раз, когда вы строите. пожалуйста, не меняйте имя переменной, хотя.
  6. если у вас есть более одного целевого объекта, добавьте следующий сценарий к первому целевому объекту, который построен перейдя к Проект > Цель > Этапы Сборки
  7. перейдите в меню "Редактор" > Добавить Этап Построения " > " Добавить Запуска Сценария
  8. A Выполнить Скрипт фаза должна быть добавлена к вашей цели; так что перетащите его, пока не находится под Целевой Зависимостей (эта деталь важна!).
  9. теперь идет интересная часть, и я объясню сценарий почти строка за строкой:

старт создав путь к PlistBuddy в первой строке скрипта:

plistbuddy="/usr/libexec/PlistBuddy"

добавьте строку 2 для чтения файла конфигурации, а затем прочитайте переменную CURRENT_PROJECT_VERSION, настроенную на шаге 5.

OLD_VERSION=`cat "$SRCROOT/BuildNumber.xcconfig" | awk '/CURRENT_PROJECT_VERSION/ { print  }'`

строка 3-11 настройте NEW_VERSION со значением bumped up, затем сохраните файл конфигурации с новым номером сборки; остальные строки должны сохранить маркетинговую версию и номер сборки в plist:

NEW_VERSION=`cat "$SRCROOT/BuildNumber.xcconfig" | awk '/CURRENT_PROJECT_VERSION/ { print  + 1 }'`
sed -i '' "s/CURRENT_PROJECT_VERSION = .*/CURRENT_PROJECT_VERSION = $NEW_VERSION/" "$SRCROOT/BuildNumber.xcconfig"
CURRENT_PROJECT_VERSION=$NEW_VERSION
BUILD_STR="Build $NEW_VERSION"
COPYRIGHT_STR="© 2017 MyCompany.net"
APP_VERSION_STR="1.3.5"
$plistbuddy -c "Set :CFBundleShortVersionString $APP_VERSION_STR" "${SRCROOT}/$TARGETNAME/Info.plist"
$plistbuddy -c "Set :CFBundleVersion $BUILD_STR" "${SRCROOT}/$EXECUTABLE_NAME/Info.plist"
$plistbuddy -c "Set :NSHumanReadableCopyright $COPYRIGHT_STR" "$INFOPLIST_FILE"

Я также показываю в строках 8-11, как использовать различные переменные среды, которые Xcode устанавливает для своих сценариев. Вы можете добавить дополнительные строки для редактирования информации.plist для других целей, а затем сохранить версию основного приложения и его помощников в синхронизации. Перейти к GitHub, скачать проект и играть с ним, а затем адаптировать его к вашим потребностям. Счастливое автоматическое управление версиями с помощью Xcode.