web-dev-qa-db-fra.com

Ajouter des fichiers à un projet Xcode à partir d'un script?

En ce moment, j'utilise quelques scripts pour générer des fichiers que j'inclus en tant que ressources dans Xcode. Le fait est que j'exécute le script, que je supprime du projet, puis que je l'ajoute de nouveau au projet. Il doit y avoir un moyen d'automatiser cette dernière étape, afin que le script puisse générer les fichiers et les ajouter automatiquement dans le projet xcode pour moi.

J'utilise bash mais tous les exemples de langue pourraient aider.

Merci, Andrew

51
Andrew

Cela peut être fait en ajoutant une nouvelle phase de construction à votre application.

  1. Dans votre navigateur de projet Xcode, recherchez la cible de votre application et développez-la pour afficher toutes les phases de génération.

  2. Ajoutez un nouveau phase de construction du "run script" à votre cible. Le moyen le plus simple est de cliquer avec le bouton droit sur la cible et de choisir "Ajouter/Nouvelle phase de construction/Nouvelle phase de construction de script d'exécution"

  3. L'ajout de la nouvelle phase de construction devrait faire apparaître une fenêtre d'inspection. Dans cette fenêtre, vous pouvez saisir l'intégralité du script Shell, ou simplement une ligne de commande pour exécuter le script.

  4. Voici l'or: au bas de la fenêtre d'inspection, vous pouvez spécifier les fichiers d'entrée et les fichiers de sortie. La spécification des fichiers d'entrée configure automatiquement les dépendances (le script Shell ne sera exécuté que si certains des fichiers d'entrée ont été modifiés). La spécification des fichiers de sortie propage automatiquement les dépendances vers ces fichiers. Lorsque votre script Shell est exécuté, Xcode sait qu'il doit gérer les fichiers que le script Shell a modifiés.

  5. Assurez-vous de faire glisser votre nouvelle phase de construction en haut de la liste des phases, comme indiqué dans la capture d'écran ci-dessous. La commande sera importante si vous avez besoin que ces fichiers de ressources soient inclus dans le bundle.

  6. Enregistrez, créez, engagez-vous dans le référentiel, demandez une augmentation, prenez l'air et passez une bonne journée! :)

33
e.James

J'avais un besoin similaire à Andrew. J'avais besoin de pouvoir inclure des ressources d'un script sans connaître ces ressources à l'avance. Voici les solutions que j'ai trouvées:

Ajoutez une nouvelle phase de génération de script d'exécution après "Copy Bundle Resource" qui contient la commande suivante:

find -L ${SRCROOT}/SomeDerivedResources \
    -type f -not -name ".*" \
    -not -name "`basename ${INFOPLIST_FILE}`" \
    | xargs -t -I {} \
    cp {} ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/

Ça a l'air effrayant, mais décomposons-le:

find -L ${SRCROOT}/SomeDerivedResources

Cela analyse le répertoire SomeDerivedResources dans notre racine source (-L lui dit de suivre les liens symboliques)

-type f

Inclure uniquement les fichiers standard

-not -name ".*"

Ignorer les fichiers commençant par un point

-not -name "`basename ${INFOPLIST_FILE}`"

Dans mon cas, mes listes d'informations vivent dans mon répertoire SomeDerivedResources, nous devons donc exclure ce fichier de la copie sur notre produit

| xargs -t -I {}

Canalisez les résultats de find dans xargs avec -t (renvoie les commandes résultantes à stderr pour qu'elles apparaissent dans notre journal de build), -I (exécutez la commande une fois pour chaque fichier d'entrée) et utilisez {} comme espace réservé à notre argument

cp {} ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/

Enfin, copiez chaque fichier trouvé (indiqué par {}) dans le répertoire de ressources de notre produit.

J'ai réalisé en tapant ceci que l'utilisation d'une configuration rsync au lieu de cp pourrait nous empêcher de copier des ressources chaque fois que vous construisez. Si vos ressources sont très importantes, cela pourrait valoir la peine d'y jeter un coup d'œil.

(De plus, une référence de dossier ne fonctionnerait pas pour mes besoins pour plusieurs raisons. Premièrement, mes icônes sont dans mon répertoire DerivedResources et les avoir dans un sous-répertoire du bundle ne semble pas fonctionner. De plus, je voulais idéalement pouvoir utilisation [UIImage imageNamed:@"MyAwesomeHappyImage.png"] et -pathForResource:ofType: (et certains de mes fichiers sont imbriqués plus loin dans mon répertoire DerivedResources). Si vos besoins ne contiennent pas ces contraintes, je fortement vous suggère de suivre la route de référence du dossier.)

35
Ben Cochran

Pour ceux qui ont un grand nombre de fichiers, pour éviter d'avoir à recopier (ou revérifier) ​​chaque fichier, comme suggéré par @Ben Cochran (merci beaucoup pour l'excellent script), voici comment le faire avec rsync:

enter image description here

11
Adriano Lucas

Fondamentalement, les fichiers doivent simplement être copiés dans le bundle principal

Dans ce cas, ajoutez simplement une référence de dossier au projet (créez un dossier dans votre dossier de projet, puis faites-le glisser dans le groupe "Ressources" de vos projets (dans la liste "Fichiers et groupes", puis dans la feuille qui apparaît, sélectionnez "Créer Références de dossier pour tout bouton radio Dossier ajouté ") et Xcode copiera le dossier et tout son contenu dans le groupe cible au moment de la construction.

Juste une note supplémentaire: si vous utilisez cette méthode pour ajouter des sous-dossiers d'image, vous devrez préfixer le nom de l'image avec le nom du sous-dossier pour utiliser '[UIImage imageNamed:]'. Par exemple, si vous avez une image nommée "Rendezvous.png" dans un sous-dossier nommé "MyImages":

"

// this won't work
UIImage * image = [UIImage imageNamed:@"Rendezvous"];
if (image) {
    NSLog(@"Found Rendezvous!");
} else {
    NSLog(@"Didn't find Rendezvous.");
}

// but this will!
image = [UIImage imageNamed:@"MyImages/Rendezvous"];
if (image) {
    NSLog(@"Found MyImages/Rendezvous!");
} else {
    NSLog(@"Didn't find MyImages/Rendezvous.");
}

"

6
geowar

Si vous avez déjà les fichiers quelque part sur votre système, par rapport à votre racine source, vous pouvez toujours ajouter ne phase "Copier les fichiers" . Cela vous permettra de spécifier un répertoire à partir duquel vos ressources doivent être copiées.

Vous pouvez combiner cela avec la réponse de la phase Build Script qui vous a déjà été fournie. Par exemple, exécutez un script pour extraire vos actifs de Subversion dans un sous-répertoire de votre projet, puis poursuivez avec une phase de copie de fichiers qui copie de "$ (SRCROOT)/Assets".

5
Michael Nachbaur

Je sais qu'il est un peu tard, mais je viens de tomber cet article expliquant comment faire quelque chose qui ressemble à ce que vous cherchez.

2
Richard