どうやらファイルはキャッシュされるので、変更されたときにのみビルドされます。ただし、バージョン番号などを増やすように環境変数を設定し、plistとは独立して(実際にはプロジェクトのビルド設定で)環境変数を更新しています。 Info.plistを強制的に更新するスクリプトビルドフェーズとして使用できるスクリプトはありますか?他の便利な方法はありますか?
[スキームの編集]を選択し、左側のコントロールから[ビルド]を選択します。
次に、事前アクションステップを追加し、[ビルド設定の提供元]プルダウンで問題のスキームが選択されていることを確認してから、これを下の編集ウィンドウに追加します。
rm "${CONFIGURATION_BUILD_DIR}/${INFOPLIST_PATH}"
これにより、キャッシュされたバージョンのInfo.plist
が削除され、ビルドを実行するたびにXCodeが再ビルドします。
または、XcodeにテンプレートのInfo.plistファイルを前処理させる場合は、テンプレートにタッチするだけです。
touch ${PROJECT_DIR}/${INFOPLIST_FILE}
も動作します。
アクション前スクリプトのデバッグ
間違いがあった場合、事前アクションのステップでは情報が提供されません。この行をスクリプトに追加することで、ビルド変数の使用をデバッグできます。
echo "${CONFIGURATION_BUILD_DIR}/${INFOPLIST_PATH}" > ~/debug.txt
次に、~/debug.txt
の内容をチェックして、プレアクションスクリプトが実行されたことを確認し、正しいパスを使用したかどうかを確認します。
私もバージョン番号を自動設定しています。 スクリプトの実行ビルドフェーズを作成しました。重要なのは、Info.plistのターゲットビルドディレクトリコピーを更新することであり、ビルドディレクトリコピーを更新することではありません。また、コピーバンドルフェーズの後に実行スクリプトを用意する必要があります。コード署名の前なので、バンドルファイルを直接編集してもかまいません。車輪を再発明するファイルを生成する必要はありません。
これが私のスクリプトです:
# ---------------------------- IMPORTANT ----------------------------
# You must set GITHash to something like 'Set by build script' in the file
# file '<Project Name>-Info.plist' in the 'Supporting Files' group
# -------------------------------------------------------------------
#
# Get the version number from the tag in git and the number of commits as the build number
#
appVersion=$(git describe --long | cut -f 1 -d "-")
appBuild=$(git describe --long | cut -f 2 -d "-")
gitHash=$(git describe --long | cut -f 3 -d "-")
echo "From GIT Version = $appVersion Build = $appBuild"
#
# Set the version info in plist file
#
/usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString $appVersion" "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}"
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $appBuild" "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}"
/usr/libexec/PlistBuddy -c "Set :GITHash $gitHash" "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}"
echo "Updated ${TARGET_BUILD_DIR}/${INFOPLIST_PATH}"
[〜#〜] fyi [〜#〜]バージョンを自動設定し、次のコードを使用して[バージョン情報]タブでビルドします
NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary];
NSString *appDisplayName = infoDictionary[@"CFBundleDisplayName"];
NSString *majorVersion = infoDictionary[@"CFBundleShortVersionString"];
NSString *minorVersion = infoDictionary[@"CFBundleVersion"];
self.appDescription.text = [NSString stringWithFormat:@"Dirty Dog Software\n%@\nVersion: %@(%@)",
appDisplayName, majorVersion, minorVersion];
touch
コマンドを使用してタイムスタンプを更新してみることもできます。これは、Xcodeが再構築する必要があるかどうかを判断するために使用しているものだと思います。
$ touch Info.plist
これを行う1つの方法は、スクリプトの実行ビルドフェーズでInfo.plist
ファイルからInfo.plist.template
を生成し、バンドルの作成後にrm Info.plist
を生成することです。コメントからのアイデア Dave DeLong 彼のブログに投稿 ここ 。
それがかなりひどくキャッシュしている場合(つまり、ファイル履歴でInfo.plistを開いていない場合でもキャッシュする)、このスクリプトでキャッシュされたバージョンをrm
することもできます。
Xcode 4では、事前ビルドアクションを使用してinfo plistを操作できます。
注:これは、スクリプトの実行ビルドフェーズと同じではありません。 Xcodeがinfo plistをチェックする前にビルド前のアクションが発生し、Xcodeがinfo plistをすでにチェックした後に実行スクリプトのビルドフェーズが発生するようです(そのため、1回おきにしか機能しません)。
touch "${SRCROOT}/${INFOPLIST_FILE}"
スクリプトボックス内ターゲットの[情報を見る]ウィンドウの[ビルド]タブの[パッケージ]にある[Info.plistファイルの前処理]というラベルの付いたオプションがあり、確認できます。ビルドごとにファイルが更新されると思います。
2013年の@LeeHの回答に触発されて、Info.plistを再構築するための2つのソリューションを考え出しました。
最も簡単な解決策は、ターゲットをInfo.plist
にtouchingして、Xcodeにカスタム変数を読み取らせることです。
ビルドフェーズを追加します。以下のスクリーンショット(元々はSolution 2のスクリーンショット)を参照して、次の行を追加してください。
touch $INFOPLIST_FILE
以上です!これで、Xcodeはカスタム変数をInfo.plist
ファイルに強制的に再ロードする必要があります。
このソリューションは@lukelutmanが提案したものと同じですが、ビルドフェーズを使用します。プレアクションスクリプトは私には機能しませんでした。
別の解決策は、ビルドディレクトリのcachedInfo.plist
を削除することです。
この超シンプルな小さなbashスクリプトを書きました
#!/bin/bash
info_plist="$CONFIGURATION_BUILD_DIR/$PRODUCT_NAME.app/Info.plist"
echo "Removing Info.plist from build dir in order to force rebuild of it and reading of correct xcconfig variables, plist path $info_plist"
rm "$info_plist"
それを保存して、ターゲットのビルドフェーズから呼び出しました。最初のビルドフェーズとして配置します。
私は3つの異なる構成:Config
、Alpha
、AppStore
を使用しており、ユニバーサルリンク、プッシュ通知、および資格ファイルの使用を必要とするその他のものを使用しています。しかし、構成ごとに1つずつ、合計3つのエンタイトルメントファイルを作成したくありませんでした。
私のプロジェクトはすでに設定ファイル(.xcconfig
)に大きく依存しています。私は実際にカスタム構成変数を使用して資格ファイル(MyAppsProductName.entitlements
)を設定しました。
しかし、同じ構成変数のランタイムを読みたかったので、それらがターゲットのInfo.plistに追加されれば、それができると考えました。うまくいった!
しかし、.xcconfig
ファイルの値を変更しても、Info.plist
ファイルの値が変更されていないことに気付きました。クリーンビルドを実行すると、Info.plist
の値が.xcconfig
ファイル内の値に従って更新されることに気付きました。 Xcodeは確かにInfo.plist
ファイルをキャッシュします。
したがって、上記のこれらのソリューションはこの問題を修正します。それが役に立てば幸い! :)
Solution 2がSolution 1...よりも有利かどうかはわかりません...おそらく誰か入力はありますか?
プロジェクトで自動バージョン管理を行うのに苦労している人のために、@ GayleDDSとDanielのアイデアのおかげで、非常に簡単で簡単な方法でプロジェクトを実装する方法を示す macOS GitHubプロジェクト を作成しました。 Farrellyと彼のブログで、バージョン管理と自分の実装について説明しています。手間をかけずに、他のプラットフォームのプロジェクトに変換できると思います。
これは、プロジェクト(Xcode 8)でそれを複製する方法の簡単なガイドです。
BuildNumber
という名前を付け、忘れないでくださいこの構成ファイルをすべてのターゲットに追加同期を維持したい;このファイルを保存する前に、それぞれのチェックボックスをクリックしてくださいBuildNumber.xcconfig
というファイルがプロジェクトに表示されるはずですCURRENT_PROJECT_VERSION = 1
。必要に応じて、別の番号から始めることができます。これは、ビルドするたびに増加するビルド番号になります。 ただし、変数の名前は変更しないでください。スクリプトの最初の行にPlistBuddyへのパスを作成することから始めます。
plistbuddy="/usr/libexec/PlistBuddy"
2行目を追加して構成ファイルを読み取り、手順5で設定したCURRENT_PROJECT_VERSION変数を読み取ります。
OLD_VERSION=`cat "$SRCROOT/BuildNumber.xcconfig" | awk '/CURRENT_PROJECT_VERSION/ { print $3 }'`
3-11行目は、バンプされた値でNEW_VERSIONを設定し、新しいビルド番号で構成ファイルを保存します。残りの行は、マーケティングバージョンとビルド番号をplistに保存するためのものです。
NEW_VERSION=`cat "$SRCROOT/BuildNumber.xcconfig" | awk '/CURRENT_PROJECT_VERSION/ { print $3 + 1 }'`
sed -i '' "s/CURRENT_PROJECT_VERSION = .*/CURRENT_PROJECT_VERSION = $NEW_VERSION/" "$SRCROOT/BuildNumber.xcconfig"
CURRENT_PROJECT_VERSION=$NEW_VERSION
BUILD_STR="Build $NEW_VERSION"
COPYRIGHT_STR="© 2017 MyCompany.net"
APP_VERSION_STR="1.3.5"
$plistbuddy -c "Set :CFBundleShortVersionString $APP_VERSION_STR" "${SRCROOT}/$TARGETNAME/Info.plist"
$plistbuddy -c "Set :CFBundleVersion $BUILD_STR" "${SRCROOT}/$EXECUTABLE_NAME/Info.plist"
$plistbuddy -c "Set :NSHumanReadableCopyright $COPYRIGHT_STR" "$INFOPLIST_FILE"
Xcodeがスクリプト用にセットアップするさまざまな環境変数を使用する方法も8〜11行目に示します。追加の行を追加して、他のターゲットのinfo.plistを編集し、メインアプリのバージョンとそのヘルパーの同期を維持できます。 GitHub に移動し、プロジェクトをダウンロードして遊んでから、ニーズに合わせてください。 Xcodeによるハッピー自動バージョン管理。
もう1つのアプローチは、ビルドフェーズのみを持つ「集約」ターゲットを作成することです。これを使用して、Info.plistファイルをタッチします。そのターゲットを、アプリを構築するターゲットの依存関係にします。
これは独立したターゲットであり、アプリターゲットの依存関係であるため、アプリターゲットのInfo.plistファイルがチェックされる前にビルドされます。 (他の場所で説明されているように、Info.plistファイルの変更時刻がすでに確認されているため、アプリターゲット自体のビルドフェーズは遅すぎます。)
Plistのビューも更新してください。
Xcodeでplistを表示するときは、plistのルート要素の横にある開示三角形をクリックするだけです(Information Property List
)。そして、もう一度クリックして展開します。
値が更新されたことがわかります。私は同様のスクリプトを実行していて、plistビューが単に更新されていないことに気付くまで、断続的にしか機能していないと思いました。