web-dev-qa-db-ja.com

Watchkitアプリのターゲットのバージョンとビルド番号を自動的に設定する方法

Watchkitアプリと拡張機能のバージョンとビルド番号(またはバージョンとショートバージョン)は、それを含むアプリと同じ値に設定する必要があります。

環境変数を使用して、ビルド時にアプリのバージョンをInfo.plistに動的に設定します。これはWatchkit拡張機能でも正常に機能しますが、Watchkitアプリでは機能しません。

私が使用する環境変数は、${}なしでメインアプリと拡張機能のplistに提供する必要があります(変数${VERSION}の場合はVERSIONを設定します)。
Watchkitアプリに対して同じことを行うと、値ではなく文字列自体を取得します。ドルと角かっこを指定すると、変数にデータがありません。

Watchkitアプリの変数を設定する方法はありますか?

25
dogsgod

まあ、それがこのように機能しない場合は、Run Script Build Phase。このようなことをしてください:

#!/bin/sh
INFOPLIST="${TARGET_BUILD_DIR}/${INFOPLIST_PATH}"
echo "writing to $INFOPLIST"
PLISTCMD="Set :CFBundleVersion $(git rev-list --all|wc -l)"
echo -n "$INFOPLIST" | xargs -0 /usr/libexec/PlistBuddy -c "$PLISTCMD"

WatchKitアプリの正しいパスがないので、自分で変更する必要があります。

4
stk

これを使用してすべてのターゲットを更新します。

#!/bin/bash
buildNumber=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "$INFOPLIST_FILE")
buildNumber=$(($buildNumber + 1))
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "$INFOPLIST_FILE"
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "$SRCROOT/Great WatchKit App/Info.plist"
19
Thomas Kekeisen

私のCFBundleVersionは、gitリポジトリのmasterブランチのコミット数です。

メインのアプリターゲットのBuild Phases> + New Run Script Phaseで、次のスクリプトを追加しました:

# Set the build number to the count of Git commits
buildNumber=$(git rev-list --count HEAD)
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "${PROJECT_DIR}/${INFOPLIST_FILE}"
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "$SRCROOT/app WatchKit Extension/Info.plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "$SRCROOT/app WatchKit App/Info.plist"

app WatchKit Appから、appはアプリの名前にする必要がありますが、正確なパスを確認してください。

14
Lucien

メインのアプリターゲットに接続する実行スクリプトがあります。アプリのビルド時にWatchKit拡張機能とWatchKitアプリを伝播します。

完全に再利用可能です。楽しい!

buildNumber=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "${PROJECT_DIR}/${INFOPLIST_FILE}")

buildNumberDec=$(($buildNumber + 1))

/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumberDec" "${PROJECT_DIR}/${INFOPLIST_FILE}"
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumberDec" "$SRCROOT/${PRODUCT_NAME} WatchKit Extension/Info.plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumberDec" "$SRCROOT/${PRODUCT_NAME} WatchKit App/Info.plist"
4
Sam Bantner

stkの答えは正しいですが、自分の調査結果も追加したかったのです。

この問題を解決する1つの方法は、agvtoolsを使用することです。

OSX>その他>外部ビルドシステムで新しいターゲットを作成します次のような実行スクリプトを追加します。

#!/bin/bash

#read vesion number from version.txt in project root
VERSION=$(head -n 1 version.txt)
BUILD=`git rev-list $(git rev-parse --abbrev-ref HEAD) | wc -l | awk '{ print $1 }'`

echo "${VERSION} (${BUILD})"

agvtool new-marketing-version ${VERSION}
agvtool new-version -all ${BUILD}

exit 0

version.txtファイルに自分のバージョン番号のみが含まれている(marketing versionまたはshort bundle version)CIシステムで簡単に調整でき、ビルド番号としてgit SHAの数を使用できます(バンドルバージョン)ソースを調整しますVERSIONBUILDは要件に合わせて

ビルド/アーカイブの前に、新しいターゲット用に作成されたスキームを実行します。

これをメインターゲットの依存関係として必要とする場合-次のターゲットの実行を停止するため、これは失敗します(誰かがそれを防ぐ方法を知っている場合は、ヒントに感謝します)

しかし、pstのそれぞれに対して次のようなスクリプトを実行することで、これを実現できます(stkが提供するものと同様)。

#!/bin/sh
#
# usage:
# set-version-in-plist.sh LIST VERSION BUILD
# LIST:      Info.plist path & name
# VERSION:   version number xxx.xxx.xxx
# BUILD:     build number xxxxx
#

# Location of PlistBuddy
PLISTBUDDY="/usr/libexec/PlistBuddy"

${PLISTBUDDY} -c "Set :CFBundleShortVersionString $2" "$1";
${PLISTBUDDY} -c "Set :CFBundleVersion $3" "$1";

このスクリプトをファイルとして保存し、実行可能にします(chmod +x SCRIPTNAME)次に、すべてのplistについて上記のパラメーターを指定して実行します

このソリューションはagvtoolsソリューションほど便利ではありませんが、依存関係で使用してもビルドが停止しないはずです...

4
dogsgod

ビルドスクリプトなしですべてのターゲットのビルドバージョンを更新できます。 (これを使用して、マーケティング/ショートビルドバージョンを更新することもできます。この場合、CFBundleVersionへの変更は無視してください)。

プロジェクト設定を開き、CURRENT_PROJECT_VERSION(現在のプロジェクトバージョン)を目的のバージョン番号に設定します。すべてのターゲットで、sur CURRENT_PROJECT_VERSIONを空にします(その値はプロジェクトから継承されます)。次に、すべてのInfo.plistファイルで、CFBundleShortVersionString(バンドルバージョンの文字列、短い)とCFBundleVersion(バンドルバージョン/ビルドバージョン)を$(CURRENT_PROJECT_VERSION)に設定します。

各ビルドでCFBundleVersionをインクリメントする場合(またはgit SHAを反映させる場合)。 dogsgodの説明に従ってagvtoolを使用するか、 https://developer.Apple.com/library/ios/qa/qa1827/_index.html を参照してください。

4
davidisdk

私自身の個人的な経験で他の答えを補足することが有用であるなら。これらは、ValidateEmbeddedBinaryによって引き起こされるビルドの失敗を中心としていました。

ValidateEmbeddedBinaryは、埋め込みWatchKitアプリと親アプリでCFBundleVersionが異なる場合に失敗します。

エラーは次のようになります。

(null):エラー:WatchKitアプリのInfo.plist(1234)のCFBundleVersionの値が、コンパニオンアプリのInfo.plist(7931)の値と一致しません。これらの値は一致する必要があります。

XCode 7.3で作業する場合、以下は最初に親アプリのplistを更新します。次に、PBXCpを実行して親アプリディレクトリにコピーする前に、DebugまたはRelease WatchKitアプリを更新します。

#!/bin/sh

git=`sh /etc/profile; which git`
appBuild=`"$git" rev-list HEAD --count`

appPlistPath="${TARGET_BUILD_DIR}/${INFOPLIST_PATH}"
watchKitPlistPath="${BUILT_PRODUCTS_DIR}/../${CONFIGURATION}-watchos/${PRODUCT_NAME} WatchKit App.app/Info.plist"

echo "Setting App CFBundleVersion $appBuild at info plist path at ${appPlistPath}"
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $appBuild" "${appPlistPath}"

echo "Setting WatchKit App CFBundleVersion $appBuild at ${watchKitPlistPath}"
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $appBuild" "${watchKitPlistPath}"

上記はgitのコミット数をCFBundleVersionとして使用しています。

3
Max MacLeod

このスレッドを拡張するには、誰かが私と同様の問題に遭遇した場合、うまくいけば、以下のスクリプトが役立つでしょう。

たとえば、私はwatch targetwatch extension、 と app share extensionプロジェクト内。

実行フェーズを使用してプロジェクトのplistを更新しましたが、プロジェクトをビルドすると、.plistファイルはすべて期待どおりに更新されます。

ただし、問題はアプリをアーカイブするとき(たとえば、すべてのターゲットのビルド番号が異なるとしましょう)、アーカイブされたプロジェクトの情報リストが更新されていません。数回試してみたところ、この実行フェーズの前に拡張機能のplistファイルがコピーされたことがわかりました。実行フェーズスクリプト(プロジェクトのplistを更新)は、アーカイブされたplistには役立ちません。そのため、最終的にスクリプトを変更して、コンパイル済みターゲットのplistを更新しました。期待どおりに機能し、アプリケーション内のすべてのターゲットに対して同じビルド番号を持っています。これが私のやり方です:このスクリプトを各ターゲットのビルドフェーズに追加します:

infoPlistPath="${TARGET_BUILD_DIR}/${EXECUTABLE_FOLDER_PATH}/Info.plist"
PLISTBUDDY="/usr/libexec/PlistBuddy"
buildNumber=$(git rev-list HEAD | wc -l | tr -d ' ')
$PLISTBUDDY -c "Set :CFBundleVersion $buildNumber" "${infoPlistPath}"

別のターゲットの場合、これはEXECUTABLE_FOLDER_PATHは異なり、プロジェクトのinfo plistではなく、コンパイルされたターゲットのinfo plistを更新します。アーカイブのために実行する必要があるだけなので、「インストール時にのみスクリプトを実行する」もチェックしたことに注意してください

1
air_bob