Notre exemple de projet a deux cibles de construction: HelloWorld.app et Helper.app. Nous créons un package de composants pour chacun et les combinons dans une archive produit .
Un package de composants contient une charge utile à installer par le programme d'installation d'OS X. Bien qu'un package de composants puisse être installé seul, il est généralement incorporé dans une archive de produit .
Après un "Build and Archive" réussi, ouvrez $ BUILT_PRODUCTS_DIR dans le Terminal.
$ cd ~/Library/Developer/Xcode/DerivedData/.../InstallationBuildProductsLocation
$ pkgbuild --analyze --root ./HelloWorld.app HelloWorldAppComponents.plist
$ pkgbuild --analyze --root ./Helper.app HelperAppComponents.plist
Cela nous donne le composant-plist, vous trouvez la description de la valeur dans la section "Liste des propriétés des composants" . pkgbuild -root génère les packages de composants , si vous n'avez pas besoin de modifier l'une des propriétés par défaut, vous pouvez omettre le paramètre --component-plist dans la commande suivante.
productbuild --synthesize donne une définition de distribution .
$ pkgbuild --root ./HelloWorld.app \
--component-plist HelloWorldAppComponents.plist \
HelloWorld.pkg
$ pkgbuild --root ./Helper.app \
--component-plist HelperAppComponents.plist \
Helper.pkg
$ productbuild --synthesize \
--package HelloWorld.pkg --package Helper.pkg \
Distribution.xml
Dans le fichier Distribution.xml, vous pouvez modifier des éléments tels que le titre, l'arrière-plan, la bienvenue, le fichier Lisez-moi, la licence, etc. Vous transformez vos packages de composants et votre définition de distribution avec cette commande en une archive de produit :
$ productbuild --distribution ./Distribution.xml \
--package-path . \
./Installer.pkg
Je recommande de jeter un œil à iTunes Installers Distribution.xml pour voir ce qui est possible. Vous pouvez extraire "Install iTunes.pkg" avec:
$ pkgutil --expand "Install iTunes.pkg" "Install iTunes"
Permet de le mettre ensemble
J'ai généralement un dossier nommé Package dans mon projet qui comprend des éléments tels que Distribution.xml, des listes de composants, des ressources et des scripts.
Ajoutez une phase de génération de script d'exécution nommée "Générer le package", qui est définie sur Exécuter le script uniquement lors de l'installation :
VERSION=$(defaults read "${BUILT_PRODUCTS_DIR}/${FULL_PRODUCT_NAME}/Contents/Info" CFBundleVersion)
PACKAGE_NAME=`echo "$PRODUCT_NAME" | sed "s/ /_/g"`
TMP1_ARCHIVE="${BUILT_PRODUCTS_DIR}/$PACKAGE_NAME-tmp1.pkg"
TMP2_ARCHIVE="${BUILT_PRODUCTS_DIR}/$PACKAGE_NAME-tmp2"
TMP3_ARCHIVE="${BUILT_PRODUCTS_DIR}/$PACKAGE_NAME-tmp3.pkg"
ARCHIVE_FILENAME="${BUILT_PRODUCTS_DIR}/${PACKAGE_NAME}.pkg"
pkgbuild --root "${INSTALL_ROOT}" \
--component-plist "./Package/HelloWorldAppComponents.plist" \
--scripts "./Package/Scripts" \
--identifier "com.test.pkg.HelloWorld" \
--version "$VERSION" \
--install-location "/" \
"${BUILT_PRODUCTS_DIR}/HelloWorld.pkg"
pkgbuild --root "${BUILT_PRODUCTS_DIR}/Helper.app" \
--component-plist "./Package/HelperAppComponents.plist" \
--identifier "com.test.pkg.Helper" \
--version "$VERSION" \
--install-location "/" \
"${BUILT_PRODUCTS_DIR}/Helper.pkg"
productbuild --distribution "./Package/Distribution.xml" \
--package-path "${BUILT_PRODUCTS_DIR}" \
--resources "./Package/Resources" \
"${TMP1_ARCHIVE}"
pkgutil --expand "${TMP1_ARCHIVE}" "${TMP2_ARCHIVE}"
# Patches and Workarounds
pkgutil --flatten "${TMP2_ARCHIVE}" "${TMP3_ARCHIVE}"
productsign --sign "Developer ID Installer: John Doe" \
"${TMP3_ARCHIVE}" "${ARCHIVE_FILENAME}"
Si vous n'avez pas à modifier le package après sa génération avec productbuild, vous pouvez supprimer les étapes pkgutil --expand
et pkgutil --flatten
. Vous pouvez également utiliser le --sign paramenter sur productbuild au lieu de courir productsign .
Signer un programme d'installation OS X
Les packages sont signés avec le certificat Developer ID Installer que vous pouvez télécharger à partir de Developer Certificate Utility .
La signature se fait avec le --sign "Developer ID Installer: John Doe"
paramètre pkgbuild , productbuild ou productsign .
Notez que si vous allez créer une archive de produit signée à l' aide de productbuild, il n'y a aucune raison de signer les packages de composants .
Tout le chemin: Copiez le package dans Xcode Archive
Pour copier quelque chose dans l'archive Xcode, nous ne pouvons pas utiliser la phase de construction du script d'exécution . Pour cela, nous devons utiliser une action de schéma.
Modifiez le schéma et développez Archive. Cliquez ensuite sur post-actions et ajoutez une nouvelle action d'exécution de script :
Dans Xcode 6:
#!/bin/bash
PACKAGES="${ARCHIVE_PATH}/Packages"
PACKAGE_NAME=`echo "$PRODUCT_NAME" | sed "s/ /_/g"`
ARCHIVE_FILENAME="$PACKAGE_NAME.pkg"
PKG="${OBJROOT}/../BuildProductsPath/${CONFIGURATION}/${ARCHIVE_FILENAME}"
if [ -f "${PKG}" ]; then
mkdir "${PACKAGES}"
cp -r "${PKG}" "${PACKAGES}"
fi
Dans Xcode 5, utilisez PKG
plutôt cette valeur pour :
PKG="${OBJROOT}/ArchiveIntermediates/${TARGET_NAME}/BuildProductsPath/${CONFIGURATION}/${ARCHIVE_FILENAME}"
Dans le cas où votre contrôle de version ne stocke pas les informations Xcode Scheme, je suggère de l'ajouter en tant que script shell à votre projet afin que vous puissiez simplement restaurer l'action en faisant glisser le script de l'espace de travail vers la post-action.
Scripting
Il existe deux types de scripts différents: JavaScript dans les fichiers de définition de distribution et les scripts Shell.
La meilleure documentation sur les scripts Shell que j'ai trouvée dans WhiteBox - PackageMaker How-to , mais lisez-la avec prudence car elle fait référence à l'ancien format de package.
Lecture supplémentaire
Problèmes connus et solutions de contournement
Volet de sélection de destination
L'utilisateur se voit proposer l'option de sélection de destination avec un seul choix - «Installer pour tous les utilisateurs de cet ordinateur». L'option apparaît visuellement sélectionnée, mais l'utilisateur doit cliquer dessus afin de procéder à l'installation, ce qui crée une certaine confusion.
La documentation d'Apples recommande d'utiliser, <domains enable_anywhere ... />
mais cela déclenche le nouveau volet de sélection de destination plus bogué qu'Apple n'utilise dans aucun de ses packages.
L'utilisation de la version obsolète <options rootVolumeOnly="true" />
vous donne l'ancien volet de sélection de destination.
Vous souhaitez installer des éléments dans le dossier d'accueil de l'utilisateur actuel.
Réponse courte: N'ESSAYEZ PAS!
Réponse longue: VRAIMENT; N'ESSAYEZ PAS! Lisez les problèmes et solutions du programme d'installation . Vous savez ce que j'ai fait même après avoir lu ceci? J'ai été assez stupide pour l'essayer. Me disant que je suis sûr qu'ils ont résolu les problèmes dans 10.7 ou 10.8.
Tout d'abord, j'ai vu de temps en temps le bogue du volet de sélection de destination mentionné ci-dessus. Cela aurait dû m'arrêter, mais je l'ai ignoré. Si vous ne voulez pas passer la semaine après la sortie de votre logiciel à répondre aux e-mails de support, ils doivent cliquer une fois sur la belle sélection bleue, NE PAS l'utiliser.
Vous pensez maintenant que vos utilisateurs sont assez intelligents pour comprendre le panneau, n'est-ce pas? Eh bien, voici une autre chose à propos de l'installation du dossier personnel, ILS NE FONCTIONNENT PAS!
Je l'ai testé pendant deux semaines sur environ 10 machines différentes avec différentes versions d'OS et autres, et cela n'a jamais échoué. Alors je l'ai expédié. Moins d'une heure après la sortie, je suis ravi des utilisateurs qui ne pouvaient tout simplement pas l'installer. Les journaux suggèrent des problèmes d'autorisation que vous ne pourrez pas résoudre.
Répétons-le donc encore une fois: nous n'utilisons pas le programme d'installation pour les installations du dossier personnel!
RTFD pour Bienvenue, Lisez-moi, Licence et Conclusion n'est pas accepté par productbuild
.
Programme d'installation pris en charge depuis le début des fichiers RTFD pour créer de jolis écrans de bienvenue avec des images, mais productbuild ne les accepte pas.
Solutions de contournement: utilisez un fichier rtf factice et remplacez-le dans le package par une fois productbuild
terminé.
Remarque: vous pouvez également avoir des images Retina dans le fichier RTFD. Utilisez des fichiers TIFF multi-images pour ceci: tiffutil -cat Welcome.tif Welcome_2x.tif -out FinalWelcome.tif
. Plus de détails .
Démarrage d'une application lorsque l'installation est effectuée avec un script BundlePostInstallScriptPath :
#!/bin/bash
LOGGED_IN_USER_ID=`id -u "${USER}"`
if [ "${COMMAND_LINE_INSTALL}" = "" ]
then
/bin/launchctl asuser "${LOGGED_IN_USER_ID}" /usr/bin/open -g PATH_OR_BUNDLE_ID
fi
exit 0
Il est important d'exécuter l'application en tant qu'utilisateur connecté et non en tant qu'utilisateur installateur. Ceci est fait avec le chemin uid de launchctl asuser . De plus, nous ne l'exécutons que lorsqu'il ne s'agit pas d'une installation en ligne de commande, effectuée avec l' outil d' installation ou Apple Remote Desktop .