web-dev-qa-db-fra.com

Comment définir automatiquement la version et le numéro de build d'une cible d'application Watchkit

La version et le numéro de build (ou la version et la version courte) d'une application Watchkit et d'une extension doivent être définis sur la même valeur que l'application conteneur.

J'utilise des variables d'environnement pour définir la version des applications dans le Info.plist dynamiquement au moment de la construction. Cela fonctionne également très bien pour l'extension Watchkit, mais pas pour l'application Watchkit.

Les variables d'environnement que j'utilise doivent être fournies dans le plist pour l'application principale et l'extension sans ${} (pour la variable ${VERSION} J'ai défini VERSION).
si je fais la même chose pour l'application Watchkit, elle prend la chaîne elle-même, pas la valeur. Si je lui donne des dollars et des parenthèses, il n'y a pas de données dans la variable.

Une idée de la façon de définir les variables pour l'application Watchkit?

25
dogsgod

Eh bien, si cela ne fonctionne pas comme ça, faites-le avec un Run Script Build Phase. Faites quelque chose comme ça:

#!/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"

Je n'ai pas les bons chemins pour votre application WatchKit, vous devrez donc changer cela vous-même.

4
stk

Je l'utilise pour mettre à jour toutes les cibles:

#!/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"
19
Thomas Kekeisen

Mon CFBundleVersion est le nombre de validations sur ma branche master sur le dépôt git.

Sur ma cible d'application principale, dans Build Phases> + New Run Script Phase J'ai ajouté ce 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"

De app WatchKit App le app doit être le nom de votre application, mais vérifiez le chemin exact.

14
Lucien

J'ai un script d'exécution que je joins à ma cible d'application principale. Il propagera l'extension WatchKit et l'application WatchKit lors de la création de l'application.

Il est complètement réutilisable. Prendre plaisir!

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"
4
Sam Bantner

la réponse de stk est juste, mais je voulais également ajouter mes conclusions.

Une façon de résoudre le problème consiste à utiliser agvtools:

Créez une nouvelle cible dans OSX> Autre> External Build Sytem Ajoutez un script d'exécution similaire à celui-ci:

#!/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

J'ai un version.txt fichier contenant uniquement mon numéro de version (version marketing ou version courte) qui peut être facilement ajusté par n'importe quel système CI et utiliser le numéro de mon git SHA comme build number (bundle version) Ajustez les sources de VERSION et BUILD pour répondre à vos besoins

Exécutez le schéma qui a été créé pour la nouvelle cible avant votre génération/archivage.

Dans le cas où vous devez avoir cela comme une dépendance pour votre cible principale - cela échouera, car cela arrêtera l'exécution des cibles suivantes (si quelqu'un sait comment empêcher cela, je serais reconnaissant pour un indice)

Mais vous pouvez toujours y parvenir avec un script comme celui-ci exécuté pour chacun de vos plists (similaire à ce que stk a fourni):

#!/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";

Enregistrez ce script en tant que fichier, rendez-le exécutable (chmod +x SCRIPTNAME) Ensuite, exécutez-le avec le paramètre mentionné pour tous vos plists

Cette solution n'est pas aussi pratique que la solution agvtools, mais elle ne devrait pas arrêter votre build lorsqu'elle est utilisée dans une dépendance ...

4
dogsgod

Vous pouvez mettre à jour la version de build de toutes vos cibles sans script de build. (Vous pouvez également l'utiliser pour mettre à jour la version marketing/version courte; dans ce cas, ignorez les modifications apportées à CFBundleVersion).

Ouvrez les paramètres de votre projet et définissez CURRENT_PROJECT_VERSION (version actuelle du projet) sur le numéro de version souhaité. Dans toutes les cibles, make sur CURRENT_PROJECT_VERSION est vide (de sorte que sa valeur est héritée du projet). Ensuite, dans tous les fichiers Info.plist, définissez CFBundleShortVersionString (chaîne de versions Bundle, courte) et CFBundleVersion (version Bundle/version de build) sur $ (CURRENT_PROJECT_VERSION).

Si vous souhaitez incrémenter votre CFBundleVersion sur chaque build (ou le faire refléter votre git SHA). Utilisez agvtool comme décrit par dogsgod ou voyez https://developer.Apple.com/library/ios/qa/qa1827/_index.html .

4
davidisdk

S'il serait utile de compléter d'autres réponses par ma propre expérience personnelle. Celles-ci étaient centrées sur l'échec de la construction provoqué par ValidateEmbeddedBinary.

ValidateEmbeddedBinary échouera si CFBundleVersion n'est pas le même dans l'application WatchKit intégrée et dans l'application parent.

L'erreur ressemble à ceci:

(null): erreur: la valeur de CFBundleVersion dans Info.plist (1234) de votre application WatchKit ne correspond pas à la valeur dans Info.plist (7931) de votre application compagnon. Ces valeurs doivent correspondre.

En travaillant dans XCode 7.3, ce qui suit mettra d'abord à jour le plist de l'application parent. Ensuite, il met à jour l'application Debug ou Release WatchKit avant que PBXCp ne s'exécute pour la copier dans le répertoire de l'application parent:

#!/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}"

Ce qui précède utilise le nombre de commit de git comme CFBundleVersion.

3
Max MacLeod

Pour étendre ce fil, si quelqu'un rencontre un problème similaire à moi, j'espère que le script ci-dessous vous aidera.

Par exemple, j'ai watch target, watch extension, Et un app share extension dans mon projet.

J'ai utilisé la phase d'exécution pour mettre à jour le plist du projet comme suggéré, et cela fonctionne si je crée le projet, les fichiers .plist sont tous mis à jour comme prévu.

Cependant, le problème est que lorsque vous archivez une application (disons que toutes les cibles ont un numéro de build différent), la liste d'informations dans les projets archivés n'a pas été mise à jour. Après quelques essais, j'ai trouvé que les fichiers plist de l'extension avaient été copiés avant cette phase d'exécution, puis le script de la phase d'exécution (mettant à jour le plist du projet) n'aidera pas avec le plist archivé. J'ai donc finalement changé le script pour mettre à jour le plist de la cible compilée, et cela fonctionne comme je m'y attendais, j'ai le même numéro de build pour toutes les cibles de l'application. Voici comment je l'ai fait: ajoutez ce script à la phase de construction de chaque cible:

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}"

Pour une cible différente, cette EXECUTABLE_FOLDER_PATH était différent, et il mettra à jour la liste d'informations compilée de la cible, au lieu de la liste d'informations du projet. Juste une note, j'ai également vérifié "Exécuter le script uniquement lors de l'installation" car je n'ai besoin que de cela pour l'archivage

1
air_bob