Наш прикладний проект має дві цілі побудови: HelloWorld.app та Helper.app. Ми робимо пакет компонентів для кожного і об'єднуємо їх в архів продуктів .
Пакет компонентів містить корисну навантаження, яка повинна бути встановлена установщиком OS X. Хоча пакет компонентів може бути встановлений самостійно, він, як правило, міститься в архіві продуктів .
Після успішного "Створення та архівування" відкрийте $ BUILT_PRODUCTS_DIR в Терміналі.
$ cd ~/Library/Developer/Xcode/DerivedData/.../InstallationBuildProductsLocation
$ pkgbuild --analyze --root ./HelloWorld.app HelloWorldAppComponents.plist
$ pkgbuild --analyze --root ./Helper.app HelperAppComponents.plist
Це дає нам компонент-список, опис значення ви знайдете в розділі "Список властивостей компонента" . pkgbuild -root генерує пакети компонентів , якщо вам не потрібно змінювати жодні властивості за замовчуванням, ви можете опустити параметр --component-plist у наступній команді.
побудова продукту --синтезує результати у визначенні розподілу .
$ 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
У Distribution.xml ви можете змінити такі речі, як назва, фон, привітання, readme, ліцензія тощо. Ви перетворюєте пакети компонентів та визначення розповсюдження за допомогою цієї команди в архів продуктів :
$ productbuild --distribution ./Distribution.xml \
--package-path . \
./Installer.pkg
Рекомендую поглянути на iTunes Installers Distribution.xml, щоб побачити, що можливо. Ви можете витягнути "Встановити iTunes.pkg" за допомогою:
$ pkgutil --expand "Install iTunes.pkg" "Install iTunes"
Давайте складемо його разом
У моєму проекті зазвичай є папка з назвою Package, яка включає такі речі, як Distribution.xml, списки компонентів, ресурси та сценарії.
Додайте етап збірки сценарію запуску під назвою "Створити пакет", який встановлено для запуску сценарію лише під час встановлення :
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}"
Якщо вам не доведеться міняти пакет після його створення за допомогою побудови продукту, ви можете позбутися від pkgutil --expand
та pkgutil --flatten
кроків. Крім того, ви можете використовувати --sign paramenter на productbuild замість запуску productsign .
Підпишіть інсталятор OS X
Пакети підписані сертифікатом встановника ID розробника, який ви можете завантажити з утиліти для розробників .
Вони підписуючи робиться з --sign "Developer ID Installer: John Doe"
параметром PKGBUILD , productbuild або productsign .
Зауважте, що якщо ви збираєтесь створити підписаний архів продуктів за допомогою збірки продуктів, немає підстав підписувати пакети компонентів .
Весь шлях: Скопіюйте пакет в архів Xcode
Щоб скопіювати щось у Архів Xcode, ми не можемо використовувати Фазу збірки скриптів . Для цього нам потрібно використовувати схему дій.
Відредагуйте схему та розгорніть Архів. Потім натисніть постові дії та додайте нову дію сценарію виконання :
У 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
У Xcode 5 використовуйте це значення для PKG
:
PKG="${OBJROOT}/ArchiveIntermediates/${TARGET_NAME}/BuildProductsPath/${CONFIGURATION}/${ARCHIVE_FILENAME}"
Якщо ваш контроль версій не зберігає інформацію про схему Xcode, я пропоную додати це як скрипт оболонки до свого проекту, щоб ви могли просто відновити дію, перетягнувши сценарій з робочої області в пост-дію.
Сценарій
Існує два різних сценарії: JavaScript у файлах із визначенням розподілу та скриптами оболонки.
Найкраща документація про сценарії оболонки, яку я знайшов у WhiteBox - PackageMaker How-to , але читайте це з обережністю, оскільки вона стосується старого формату пакету.
Додаткове читання
Відомі проблеми та обхідні шляхи
Виберіть область призначення
Користувачеві надається опція вибору пункту призначення лише з одним вибором - "Встановити для всіх користувачів цього комп'ютера". Параметр видається візуально вибраним, але користувачеві потрібно натиснути на нього, щоб продовжити встановлення, викликаючи певну плутанину.
Документація щодо яблук рекомендує використовувати, <domains enable_anywhere ... />
але це запускає нову більш помилкову панель вибору пункту призначення, яку Apple не використовує ні в одному зі своїх пакунків.
За допомогою депрекату <options rootVolumeOnly="true" />
ви отримаєте стару панель вибору пункту призначення.
Ви хочете встановити елементи в домашню папку поточного користувача.
Коротка відповідь: НЕ Спробуйте його!
Довга відповідь: дійсно; НЕ СТІЙТЕ ЇЇ! Прочитайте Проблеми та рішення інсталятора . Ви знаєте, що я зробив, навіть прочитавши це? Я був досить дурний, щоб спробувати це. Розповідаючи про себе, я впевнений, що вони виправили проблеми в 10.7 або 10.8.
Перш за все я час від часу бачив вищезгаданий помилка вибору пункту призначення. Це мало мене зупинити, але я проігнорував це. Якщо ви не хочете витрачати тиждень після того, як ви випустили програмне забезпечення, відповідаючи на електронні листи з підтримкою, що вони повинні натиснути, як тільки приємний синій вибір НЕ використовувати це.
Тепер ви думаєте, що ваші користувачі досить розумні, щоб зрозуміти панель, чи не так? Ну ось ще одна річ про встановлення домашньої папки - НЕ РОБОТИ!
Я тестував її протягом двох тижнів на приблизно 10 різних машинах з різними версіями ОС і що ні, і ніколи не виходив з ладу. Тож я його відвантажив. Протягом години після випуску я повернувся до користувачів, які просто не змогли його встановити. Журнали натякали на проблеми з дозволом, які ви не зможете виправити.
Тож повторимо це ще раз: ми не використовуємо Інсталятор для встановлення домашньої папки!
RTFD для Ласкаво просимо, Read-me, Ліцензія та Висновок не приймаються productbuild
.
Інсталятор підтримує RTFD-файли з самого початку, щоб створити гарні екрани привітання із зображеннями, але збірка продуктів не приймає їх.
Обхідні шляхи: Використовуйте фіктивний rtf файл і замініть його в пакеті на після того, як productbuild
буде зроблено.
Примітка. У файлі RTFD також можуть бути зображення Retina. Використовуйте для цього файли з декількома зображеннями tiffutil -cat Welcome.tif Welcome_2x.tif -out FinalWelcome.tif
. Більше деталей .
Запуск програми, коли встановлення виконується за допомогою сценарію 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
Важливо запускати додаток як зареєстрований користувач, а не як користувач, який встановлює програму. Це робиться за допомогою uid шляху запуску asuser . Крім того, ми запускаємо його лише тоді, коли це не встановлення командного рядка, виконане за допомогою інструмента інсталятора або Apple Remote Desktop .