Как автоматически установить версию и построить номер целевого приложения Watchkit
Номер версии и сборки (или версия и короткая версия) приложения и расширения Watchkit должны быть установлены на то же значение, что и содержащее приложение.
Я использую переменные среды для динамической установки версии приложений в Info.plist
во время сборки. Это также отлично подходит для расширения Watchkit, но не для приложения Watchkit.
Используемые переменные среды должны быть предоставлены в plist для основного приложения и расширения без ${}
(для переменной ${VERSION}
я set VERSION
).
если я делаю то же самое для приложения Watchkit, он берет строку, а не значение. Если я дам ему доллар и скобки, в переменной нет данных.
Любая идея, как установить переменные для приложения Watchkit?
Ответы
Ответ 1
Хорошо, если он не работает так, сделайте это с помощью Run Script Build Phase
. Сделайте что-то вроде этого:
#!/bin/sh
INFOPLIST="${TARGET_BUILD_DIR}/${INFOPLIST_PATH}"
echo "writing to $INFOPLIST"
PLISTCMD="Set :CFBundleVersion $(git rev-list --all|wc -l)"
echo -n "$INFOPLIST" | xargs -0 /usr/libexec/PlistBuddy -c "$PLISTCMD"
У меня нет правильных путей для вашего приложения WatchKit, поэтому вам придется изменить это самостоятельно.
Ответ 2
Я использую это для обновления всех целей:
#!/bin/bash
buildNumber=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "$INFOPLIST_FILE")
buildNumber=$(($buildNumber + 1))
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "$INFOPLIST_FILE"
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "$SRCROOT/Great WatchKit App/Info.plist"
Ответ 3
My CFBundleVersion
- количество коммитов на моей ветке master
в репозитории git.
В моей основной целевой программе приложения в Build Phases
> + New Run Script Phase
я добавил этот script:
# Set the build number to the count of Git commits
buildNumber=$(git rev-list --count HEAD)
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "${PROJECT_DIR}/${INFOPLIST_FILE}"
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "$SRCROOT/app WatchKit Extension/Info.plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "$SRCROOT/app WatchKit App/Info.plist"
Из app WatchKit App
app
должно быть имя вашего приложения, но проверьте точный путь.
Ответ 4
Ответ stk прав, но я хотел также добавить свои выводы.
Одним из способов решения проблемы является использование agvtools
:
Создать новую цель в OSX > Другое > External Build Sytem
Добавьте прогон script, похожий на этот:
#!/bin/bash
#read vesion number from version.txt in project root
VERSION=$(head -n 1 version.txt)
BUILD=`git rev-list $(git rev-parse --abbrev-ref HEAD) | wc -l | awk '{ print $1 }'`
echo "${VERSION} (${BUILD})"
agvtool new-marketing-version ${VERSION}
agvtool new-version -all ${BUILD}
exit 0
У меня есть файл version.txt
, в котором есть только номер моей версии (версия для маркетинга или версия с коротким пакетом), которую можно легко настроить любой системой CI и использовать номер моего git SHAs как номер сборки (версия пакета )
Отрегулируйте источники для VERSION
и BUILD
в соответствии с вашими требованиями
Запустите схему, созданную для новой цели, перед вашей сборкой/архивированием.
Если вам нужно иметь это как зависимость для вашей основной цели - это не удастся, так как это остановит выполнение следующих целей (если кто-то знает, как это предотвратить, я был бы благодарен за подсказку)
Но вы все равно можете достичь этого с помощью script, как показано ниже для каждого из ваших plists (аналогично тому, что предоставил stk):
#!/bin/sh
#
# usage:
# set-version-in-plist.sh LIST VERSION BUILD
# LIST: Info.plist path & name
# VERSION: version number xxx.xxx.xxx
# BUILD: build number xxxxx
#
# Location of PlistBuddy
PLISTBUDDY="/usr/libexec/PlistBuddy"
${PLISTBUDDY} -c "Set :CFBundleShortVersionString $2" "$1";
${PLISTBUDDY} -c "Set :CFBundleVersion $3" "$1";
Сохраните этот script как файл, сделайте его выполнимым (chmod +x SCRIPTNAME
)
Затем выполните его с указанным параметром для всех ваших plists
Это решение не так удобно, как решение agvtools
, но оно не должно останавливать вашу сборку при использовании в зависимости...
Ответ 5
Вы можете обновить версию сборки всех ваших целей без сборки script. (Вы также можете использовать это, чтобы обновить версию маркетинга/короткой сборки, в этом случае игнорировать изменения в CFBundleVersion).
Откройте параметры проекта и установите CURRENT_PROJECT_VERSION (Текущая версия проекта) на нужный номер версии. Во всех целях make sur CURRENT_PROJECT_VERSION пуст (так что его значение наследуется от проекта). Затем во всех файлах Info.plist установите CFBundleShortVersionString (строки версии, короткие) и CFBundleVersion (версия Bundle/версия сборки) в $(CURRENT_PROJECT_VERSION).
Если вы хотите увеличить ваш CFBundleVersion на каждой сборке (или чтобы он отражал ваш git SHA). Используйте agvtool, как описано doggod, или см. https://developer.apple.com/library/ios/qa/qa1827/_index.html.
Ответ 6
У меня есть Run Script, который я прикрепляю к моей основной целевой программе. Он будет распространять расширение WatchKit и приложение WatchKit при создании приложения.
Это полностью повторное использование. Наслаждайтесь!
buildNumber=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "${PROJECT_DIR}/${INFOPLIST_FILE}")
buildNumberDec=$(($buildNumber + 1))
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumberDec" "${PROJECT_DIR}/${INFOPLIST_FILE}"
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumberDec" "$SRCROOT/${PRODUCT_NAME} WatchKit Extension/Info.plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumberDec" "$SRCROOT/${PRODUCT_NAME} WatchKit App/Info.plist"
Ответ 7
Если было бы полезно дополнить другие ответы своим личным опытом. Это вызвано сбоем сборки, вызванным ValidateEmbeddedBinary
.
ValidateEmbeddedBinary
завершится с ошибкой, если CFBundleVersion
не является одинаковым во встроенном приложении WatchKit и родительском приложении.
Ошибка выглядит примерно так:
(null): error: значение CFBundleVersion в приложении WatchKit Info.plist(1234) не соответствует значению вашего приложения-компаньона Info.plist(7931). Эти значения должны соответствовать.
Работая в XCode 7.3, сначала будет обновлено родительское приложение. Затем он обновляет приложение Debug или Release WatchKit до выполнения PBXCp
, чтобы скопировать его в родительский каталог приложения:
#!/bin/sh
git=`sh /etc/profile; which git`
appBuild=`"$git" rev-list HEAD --count`
appPlistPath="${TARGET_BUILD_DIR}/${INFOPLIST_PATH}"
watchKitPlistPath="${BUILT_PRODUCTS_DIR}/../${CONFIGURATION}-watchos/${PRODUCT_NAME} WatchKit App.app/Info.plist"
echo "Setting App CFBundleVersion $appBuild at info plist path at ${appPlistPath}"
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $appBuild" "${appPlistPath}"
echo "Setting WatchKit App CFBundleVersion $appBuild at ${watchKitPlistPath}"
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $appBuild" "${watchKitPlistPath}"
В приведенном выше примере используется git commit count как CFBundleVersion
.
Ответ 8
Чтобы расширить этот поток, если кто-то сталкивается с подобной проблемой, как я, надеюсь, script ниже поможет.
Например, у меня есть цель просмотра, расширение для просмотра, расширение доли приложения в моем проекте.
Я использовал фазу выполнения, чтобы обновить проектную панель, как было предложено, и она работает, если я создаю проект. Файлы .plist обновлены, как ожидалось.
Однако проблема заключается в том, когда вы архивируете приложение (пусть все цели имеют разные номера сборки), информация в архивных проектах не обновлялась.
После нескольких попыток, я обнаружил, что файлы расширения plist были скопированы до этой фазы запуска, а затем фаза запуска script (обновление проекта plist) не поможет с архивированным plist.
Поэтому я в конечном итоге изменил script, чтобы обновить скомпилированный целевой слой, и он работает так, как я ожидал, у меня есть тот же номер сборки для всех целей в приложении.
Вот как я это сделал:
добавьте этот script в каждую фазу сборки цели:
infoPlistPath="${TARGET_BUILD_DIR}/${EXECUTABLE_FOLDER_PATH}/Info.plist"
PLISTBUDDY="/usr/libexec/PlistBuddy"
buildNumber=$(git rev-list HEAD | wc -l | tr -d ' ')
$PLISTBUDDY -c "Set :CFBundleVersion $buildNumber" "${infoPlistPath}"
Для разных целей этот EXECUTABLE_FOLDER_PATH
был другим, и он будет обновлять скомпилированный целевой информационный plist, а не информацию о проекте.
Просто примечание, которое я проверил: "Запустите script только при установке", так как мне нужно только это для запуска архивации