web-dev-qa-db-fra.com

Comment forcer Xcode à reconstruire le fichier Info.plist dans mon projet chaque fois que je le construit?

Apparemment, le fichier est mis en cache, il est donc construit uniquement lorsqu’il est modifié. J'ai des variables d'environnement définies pour incrémenter mon numéro de version, etc., et les mettre à jour indépendamment du plist (dans les paramètres de construction du projet, en fait). Existe-t-il un script que je peux utiliser en tant que phase de construction de script pour forcer la mise à jour de Info.plist? Un autre moyen pratique?

24
TraxusIV

Sélectionnez 'Edit Scheme', puis sélectionnez 'Build' dans le contrôle à gauche.

Ajoutez ensuite une étape Pré-actions, assurez-vous que le schéma en question est sélectionné dans la liste déroulante "Fournir les paramètres de construction à partir de", puis ajoutez-le dans la fenêtre d'édition ci-dessous:

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

Cela supprimera la version mise en cache de Info.plist, ce qui obligera XCode à la reconstruire à chaque fois que vous appuierez sur la construction.

Sinon, si vous laissez Xcode pré-traiter un fichier de modèle Info.plist, il vous suffit de toucher le modèle avec

touch ${PROJECT_DIR}/${INFOPLIST_FILE}

fonctionne aussi.

Débogage des scripts de pré-action

Les étapes préalables ne fournissent aucune information lorsque vous avez commis une erreur. Vous pouvez déboguer l'utilisation de vos variables de construction en ajoutant cette ligne au script

echo "${CONFIGURATION_BUILD_DIR}/${INFOPLIST_PATH}" > ~/debug.txt

Ensuite, vérifiez le contenu de ~/debug.txt pour vérifier que le script de pré-action a été exécuté et pour voir si vous avez utilisé le bon chemin.

16
LeeH

Moi aussi j'ai automatisé la définition de mes numéros de version. J'ai créé un Run Script Build Phase. La clé consiste à mettre à jour la copie du répertoire de construction cible du répertoire Info.plist, pas un. Vous devez également disposer de votre script d’exécution après la phase de regroupement des copies. C'est ok pour éditer le fichier de paquet directement parce que c'est avant la signature du code. Vous ne voulez pas générer le fichier qui réinvente la roue.

Voici mon script:

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

FYIJ'ai également défini automatiquement la version et construit sous l'onglet À propos de avec le code suivant

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];                           
14
GayleDDS

Vous pouvez essayer d'utiliser la commande touch pour mettre à jour l'horodatage, ce qui, je suppose, est ce que Xcode utilise pour déterminer s'il doit être reconstruit, par exemple.

$ touch Info.plist
11
bosmacs

Une façon de procéder consiste à avoir une phase de génération de script d'exécution pour générer Info.plist à partir d'un fichier Info.plist.template, puis à rm Info.plist après la création de l'ensemble. Idée tirée d'un commentaire Dave DeLong posté sur son blog ici .

Si la mise en cache est assez sévère (c'est-à-dire même si vous n'avez pas ouvert Info.plist dans l'historique des fichiers), vous voudrez peut-être rm la version mise en cache également dans ce script.

9
darvids0n

Dans Xcode 4, vous pouvez utiliser une action de pré-génération pour toucher le pliste info.

Remarque: Il ne s'agit pas d'une phase de génération de script d'exécution. Une action de pré-génération se produit avant que Xcode vérifie le pli info, une phase de construction de script d'exécution semble avoir lieu après que Xcode ait déjà vérifié le pli info (c'est pourquoi il ne fonctionne que toutes les deux fois).

  1. Allez dans Edit Scheme> Build> Pre-actions
  2. Cliquez sur le bouton "+" et choisissez "Nouvelle action de script d'exécution".
  3. Choisissez votre cible dans la liste déroulante "Fournir les paramètres de construction à partir de".
  4. Ajouter touch "${SRCROOT}/${INFOPLIST_FILE}" dans la boîte de script
5
lukelutman

Il existe une option dans l'onglet "Générer" de la fenêtre Lire les informations de la cible, vers le bas dans "Conditionnement", intitulée "Fichier de prétraitement Info.plist" que vous pouvez vérifier. Je crois que cela mettra à jour le fichier à chaque construction.

1
ExitToShell

Travailler avec Xcode 8.3.2

Inspiré par la réponse de @LeeH à partir de 2013, j'ai proposé deux solutions pour reconstruire Info.plist.

Solution 1: le plus simple et élégant

La solution la plus simple consiste à forcer Xcode à lire vos variables personnalisées en touchant vos cibles Info.plist.

Ajoutez une phase de construction, voir la capture d'écran ci-dessous (à l'origine capture pour Solution 2), et ajoutez simplement cette ligne:

touch $INFOPLIST_FILE

C'est tout! Maintenant, Xcode devrait forcer le rechargement de vos variables personnalisées dans le fichier Info.plist.

Cette solution est identique à celle suggérée par @lukelutman, mais en utilisant la phase de construction. Le script de pré-action n'a pas fonctionné pour moi.

Solution 2: plus complexe et hacky

Une autre solution consiste à supprimer le cached Info.plist dans le répertoire de construction .

J'ai écrit ce petit script super simple

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

Je l'ai ensuite sauvegardé et appelé à partir des phases de construction de la cible. Je le mets comme la première phase de construction.

 enter image description here

Contexte:

J'ai trois configurations différentes: Config, Alpha, AppStore et j'utilise des liens universels, des notifications push et d'autres éléments nécessitant l'utilisation d'un fichier de droits. Mais je ne voulais pas avoir trois fichiers de droits, un pour chaque configuration.

Mon projet repose déjà beaucoup sur les fichiers de configuration (.xcconfig). En fait, j'ai configuré le fichier de droits (MyAppsProductName.entitlements) à l'aide de variables de configuration personnalisées.

Mais je voulais lire le même runtime des variables de configuration, je me suis dit que je pouvais le faire si elles étaient ajoutées à mes cibles Info.plist. Ce qui a fonctionné!

Mais j'ai remarqué que lorsque j'ai modifié les valeurs dans mon fichier .xcconfig, le fichier Info.plist ne modifiait pas la valeur. J'ai remarqué que si j'effectuais une construction propre, les valeurs du Info.plist ont été mises à jour en fonction des valeurs contenues dans le fichier .xcconfig. Xcode met effectivement le fichier Info.plist en cache.

Donc, ces solutions ci-dessus résout ce problème. J'espère que ça aide! :)

Discussion

Je ne sais pas du tout si (Solution 2} _ _ a un avantage par rapport à Solution 1... Probablement pas? Une entrée quelqu'un?

0
Sajjon

Pour ceux qui ont eu du mal à faire en sorte qu'un projet utilise le versioning automatique, j'ai créé un projet macOS GitHub qui montre comment le mettre en œuvre de manière simple et directe, grâce aux idées de @GayleDDS et de Daniel Farrelly. blog sur la gestion des versions et une mise en œuvre de la mienne Je pense que vous pouvez le traduire sans problème dans vos projets sur d’autres plateformes.

Voici un petit guide sur la manière de le répliquer dans vos projets (Xcode 8).

  1. Pour réduire les risques d'erreur, assurez-vous d'avoir déjà ajouté tous vos objectifs à votre projet.
  2. Allez dans le menu Fichier> Nouveau fichier ... puis faites défiler vers le bas et choisissez Fichier de paramètres de configuration
  3. Nommez-la BuildNumber et n'oubliez pas de ajoutez ce fichier de configuration à toutes les cibles vous voulez rester synchronisé; faites-le en cliquant sur les cases correspondantes avant de sauvegarder ce fichier
  4. Vous devriez voir un fichier appelé BuildNumber.xcconfig apparaître dans votre projet
  5. Ajoutez à ce fichier le texte suivant: CURRENT_PROJECT_VERSION = 1. Si vous le souhaitez, vous pouvez commencer avec un autre numéro. Cela va être votre numéro de build qui sera augmenté chaque fois que vous construirez. Veuillez ne pas changer le nom de la variable, bien que .
  6. Si vous avez plusieurs cibles, ajoutez le script suivant à la première cible générée en accédant à Projet> Cible> Générer des phases
  7. Naviguez jusqu'au menu Editeur> Ajouter une phase de construction> Ajouter une phase de script
  8. Un Exécuter le script phase aurait dû être ajouté à votre cible; alors faites-le glisser jusqu'à ce que se trouve sous Dépendances cibles (ce détail est important!).
  9. Maintenant vient la partie intéressante et je vais expliquer le script presque ligne par ligne:

Commencez par créer un chemin d'accès à PlistBuddy dans la première ligne du script:

plistbuddy="/usr/libexec/PlistBuddy"

Ajoutez la ligne 2 pour lire le fichier de configuration, puis lisez la variable CURRENT_PROJECT_VERSION que vous avez définie à l’étape 5.

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

Ligne 3-11, configurez NEW_VERSION avec la valeur modifiée, puis enregistrez le fichier de configuration avec le nouveau numéro de version; les lignes restantes sont destinées à enregistrer la version marketing et le numéro de build sur le plist:

NEW_VERSION=`cat "$SRCROOT/BuildNumber.xcconfig" | awk '/CURRENT_PROJECT_VERSION/ { print $3 + 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"

Je montre également aux lignes 8 à 11 comment utiliser différentes variables d'environnement configurées par Xcode pour ses scripts. Vous pouvez ajouter des lignes supplémentaires pour modifier le fichier info.plist pour d'autres cibles, puis synchroniser la version de votre application principale et de ses aides. Allez sur GitHub , téléchargez le projet et jouez-le, puis adaptez-le à vos besoins. Bonne gestion automatique des versions avec Xcode.

0
jvarela

Une autre approche consiste à créer une cible "agrégée" qui ne comporte qu'une phase de construction. Utilisez cela pour toucher le fichier Info.plist. Faites de cette cible une dépendance de la cible qui construit votre application.

Comme il s'agit d'une cible distincte et d'une dépendance de votre cible d'application, elle sera créée avant même que les fichiers Info.plist de votre cible d'application ne soient vérifiés. (Comme indiqué ailleurs, les phases de construction de la cible d'application elle-même ont lieu trop tard, après que l'heure de modification des fichiers Info.plist a déjà été vérifiée.)

0
Ken Thomases

Assurez-vous également d'actualiser votre vue du plist.
Lorsque vous visualisez la liste de diffusion dans Xcode, cliquez simplement sur le triangle d'affichage situé en regard de l'élément racine dans la liste de sélection (Information Property List). Et puis cliquez à nouveau pour l'agrandir.
Vous verrez que les valeurs ont été actualisées. J'exécutais un script similaire et pensais qu'il ne fonctionnait que par intermittence jusqu'à ce que je réalise que la vue Plist n'était tout simplement pas rafraîchissante.

0
Andrew