サンプル プロジェクトには、HelloWorld.app と Helper.app の 2 つのビルド ターゲットがあります。それぞれのコンポーネント パッケージを作成し、製品アーカイブにまとめます。
コンポーネント パッケージには、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
これにより、component-plist が得られます。値の説明は、「コンポーネント プロパティ リスト」セクションにあります。pkgbuild -rootはコンポーネント パッケージを生成します。デフォルトのプロパティを変更する必要がない場合は、次のコマンドで--component-plistパラメータを省略できます。
productbuild --synthesizeはディストリビューション定義になります。
$ 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 を参照することをお勧めします。次のコマンドで「Install iTunes.pkg」を抽出できます。
$ pkgutil --expand "Install iTunes.pkg" "Install iTunes"
まとめてみましょう
私は通常、プロジェクトに Package という名前のフォルダーを持っています。このフォルダーには、Distribution.xml、コンポーネント plists、リソース、スクリプトなどが含まれています。
「パッケージの生成」という名前のRun Script Build フェーズを追加します。これは、インストール時にのみスクリプトを実行するように設定されています。
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}"
productbuildで生成された後にパッケージを変更する必要がない場合は、pkgutil --expand
との手順を取り除くことができpkgutil --flatten
ます。また、 productsignを実行する代わりに、productbuildで--signパラメータを使用することもできます。
OS X インストーラーに署名する
パッケージは、 Developer Certificate UtilityからダウンロードできるDeveloper ID Installer証明書で署名されています。
それらの署名は、 pkgbuild、productbuildまたはproductsign--sign "Developer ID Installer: John Doe"
のパラメーターを使用して行われます。
productbuild を使用して署名済みの製品アーカイブを作成する場合、コンポーネント パッケージに署名する必要はありません。

ずっと: パッケージを Xcode アーカイブにコピーする
何かを Xcode アーカイブにコピーするために、Run Script Build Phaseを使用することはできません。これには、Scheme アクションを使用する必要があります。
スキームを編集し、アーカイブを展開します。次に、post-action をクリックして、New Run Script Actionを追加します。
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とシェル スクリプトの 2 種類があります。
WhiteBox - PackageMaker How-toで見つけたシェル スクリプトに関する最良のドキュメントですが、これは古いパッケージ形式を参照しているため、注意して読んでください。
アップルシリコン
パッケージを arm64 として実行するには、Distribution ファイルのセクションで、以下に加えhostArchitectures
てサポート対象を指定する必要があります。arm64
x86_64
<options hostArchitectures="arm64,x86_64" />
追加資料
既知の問題と回避策
宛先選択ペイン
ユーザーには、「このコンピューターのすべてのユーザーにインストールする」という 1 つの選択肢しかない宛先選択オプションが提示されます。このオプションは視覚的に選択されているように見えますが、ユーザーはインストールを続行するためにそれをクリックする必要があるため、混乱が生じます。

Apple のドキュメントでは使用を推奨しています<domains enable_anywhere ... />
が、これにより、Apple がどのパッケージでも使用していない、よりバグのある新しい宛先選択ペインがトリガーされます。
非推奨<options rootVolumeOnly="true" />
を使用すると、古い宛先選択ペインが表示されます。

アイテムを現在のユーザーのホーム フォルダーにインストールします。
簡単な答え:試さないでください。
長い答え:本当に; 試さないでください!インストーラーの問題と解決策をお読みください。これを読んだ後でも、私が何をしたか知っていますか?私はそれを試すほど愚かでした。10.7または10.8で問題が修正されたと確信しています。
まず、上記の宛先選択ペインのバグをときどき見ました。それは私を止めるべきだったが、私はそれを無視した. ソフトウェアをリリースしてから 1 週間、サポートの電子メールに返信するのに時間を費やしたくない場合は、青色の素敵な選択を 1 回クリックする必要があります。これは使用しないでください。
あなたは今、あなたのユーザーがパネルを理解するのに十分賢いと考えていますよね? さて、ここでホーム フォルダのインストールに関するもう 1 つのことがあります。それらは機能しません。
OS のバージョンが異なる約 10 台のマシンで 2 週間テストしましたが、失敗することはありませんでした。なので発送しました。リリースから 1 時間以内に、インストールできなかったユーザーから返信があります。ログは、修正できない権限の問題を示唆していました。
もう一度繰り返しましょう。ホーム フォルダのインストールにインストーラは使用しません。
ようこそ、Read-me、ライセンス、結論の RTFD は によって受け入れられませんproductbuild
。
インストーラーは最初から RTFD ファイルをサポートして、画像付きのきれいなウェルカム スクリーンを作成しましたが、productbuild はそれらを受け入れません。
回避策: ダミーの rtf ファイルを使用し、完了後にパッケージ内で置き換えますproductbuild
。
注: RTFD ファイル内に Retina 画像を含めることもできます。これには複数画像の tiff ファイルを使用します: 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
インストーラー ユーザーとしてではなく、ログイン ユーザーとしてアプリを実行することが重要です。これはlaunchctl asuser uid pathで行われます。また、インストーラーツールまたはApple Remote Desktopを使用して、コマンド ライン インストールでない場合にのみ実行します。