どうやらファイルはキャッシュされるので、変更されたときにのみビルドされます。ただし、バージョン番号などをインクリメントするように環境変数を設定し、plistとは関係なく(実際にはプロジェクトビルド設定で)更新します。Info.plistを強制的に更新するスクリプトビルドフェーズとして使用できるスクリプトはありますか?他の便利な方法はありますか?
10 に答える
[スキームの編集]を選択し、左側のコントロールから[ビルド]を選択します。
次に、事前アクションステップを追加し、[ビルド設定の提供元]プルダウンで問題のスキームが選択されていることを確認してから、これを下の編集ウィンドウに追加します。
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のターゲットビルドディレクトリコピーを更新することであり、ディレクトリ1をビルドすることではありません。また、コピーバンドルフェーズの後に実行スクリプトを用意する必要があります。コード署名の前なので、バンドルファイルを直接編集してもかまいません。車輪の再発明を行うファイルを生成したくありません。
これが私のスクリプトです:
# ---------------------------- 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}"
参考までに、バージョンを自動設定し、次のコードを使用して[バージョン情報]タブでビルドします
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
Info.plist
これを行う1つの方法は、Info.plist.template
ファイルから生成するスクリプトの実行ビルドフェーズを実行rm Info.plist
し、バンドルを作成した後に実行することです。DaveDeLongが彼のブログに投稿したコメントからのアイデアはこちらです。
キャッシュがかなり厳しくなっている場合(つまり、ファイル履歴でInfo.plistを開いていない場合でもキャッシュしている場合)rm
、このスクリプトでもキャッシュされたバージョンを使用することをお勧めします。
Xcode 4では、ビルド前のアクションを使用して情報plistに触れることができます。
注:これは、スクリプトのビルドフェーズの実行と同じではありません。ビルド前のアクションは、Xcodeがinfo plistをチェックする前に発生し、スクリプトのビルドフェーズは、Xcodeがすでにinfo plistをチェックした後に発生するようです(これが、1回おきにしか機能しない理由です)。
- [スキームの編集]>[ビルド]>[事前アクション]に移動します
- 「+」ボタンをクリックして、「新規実行スクリプトアクション」を選択します
- [ビルド設定の提供元]ドロップダウンでターゲットを選択します
touch "${SRCROOT}/${INFOPLIST_FILE}"
スクリプトボックスに追加
ターゲットの[情報を見る]ウィンドウの[ビルド]タブの[パッケージ]にある[Info.plistファイルの前処理]というラベルの付いたオプションを確認できます。ビルドごとにファイルが更新されると思います。
Xcode8.3.2での作業
2013年の@LeeHの回答に触発されて、Info.plistを再構築するための2つのソリューションを考え出しました。
解決策1:最もシンプルでエレガント
最も簡単な解決策は、ターゲットに触れることInfo.plist
でXcodeにカスタム変数の読み取りを強制することです。
ビルドフェーズを追加します。以下のスクリーンショット(元々はソリューション2のスクリーンショット)を参照して、次の行を追加してください。
touch $INFOPLIST_FILE
以上です!これで、Xcodeはカスタム変数をInfo.plist
ファイルに強制的に再ロードする必要があります。
このソリューションは@lukelutmanが提案したものと同じですが、ビルドフェーズを使用します。プレアクションスクリプトは私には機能しませんでした。
解決策2:より複雑でハッキー
別の解決策は、ビルドディレクトリにキャッシュさ れているものを削除することです。Info.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
ファイルをキャッシュします。
したがって、上記のこれらのソリューションはこの問題を修正します。それが役に立てば幸い!:)
討論
ソリューション2がソリューション1よりも優れているかどうかはわかりません...おそらくそうではありませんか?誰か入力はありますか?
plistのビューも更新してください。
Xcodeでplistを表示するときは、plistのルート要素の横にある開示三角形をクリックするだけです(Information Property List
)。次に、もう一度クリックして展開します。
値が更新されたことがわかります。私は同様のスクリプトを実行していて、plistビューが単に更新されていないことに気付くまで、断続的にしか機能していないと思いました。
もう1つのアプローチは、ビルドフェーズのみを持つ「集約」ターゲットを作成することです。これを使用して、Info.plistファイルをタッチします。そのターゲットを、アプリを構築するターゲットの依存関係にします。
これは別個のターゲットであり、アプリターゲットの依存関係であるため、アプリターゲットのInfo.plistファイルがチェックされる前にビルドされます。(他の場所で説明したように、Info.plistファイルの変更時刻がすでに確認されているため、アプリターゲット自体のビルドフェーズは遅すぎます。)
プロジェクトで自動バージョン管理を行うのに苦労している人のために、@GayleDDSとDanielFarrellyのアイデアと、バージョン管理に関する彼のブログのおかげで、非常に簡単でわかりやすい方法でプロジェクトを実装する方法を示すmacOSGitHubプロジェクトを作成しました。私自身のいくつかの実装。手間をかけずに、他のプラットフォームのプロジェクトに変換できると思います。
これは、プロジェクト(Xcode 8)でそれを複製する方法の簡単なガイドです。
- これを間違える可能性を減らすために、事前にすべてのターゲットをプロジェクトに追加していることを確認してください。
- メニューの[ファイル]>[新しいファイル... ]に移動し、下にスクロールして[構成設定ファイル]を選択します。
- 名前を付けて、同期を維持したいすべてのターゲットにこの構成ファイルを追加すること
BuildNumber
を忘れないでください。このファイルを保存する前に、それぞれのチェックボックスをクリックしてください。 BuildNumber.xcconfig
プロジェクトにshowと呼ばれるファイルが表示されます。- このファイルに次のテキストを追加します
CURRENT_PROJECT_VERSION = 1
。必要に応じて、別の番号から始めることができます。これは、ビルドするたびに増加するビルド番号になります。ただし、変数の名前は変更しないでください。 - 複数のターゲットがある場合は、[プロジェクト]>[ターゲット]>[ビルドフェーズ]に移動してビルドされる最初のターゲットに次のスクリプトを追加します
- メニューの[エディター]>[ビルドフェーズの追加]>[実行スクリプトフェーズの追加]に移動します
- スクリプトの実行フェーズがターゲットに追加されている必要があります。したがって、[ターゲットの依存関係]の下に表示されるまでドラッグします(この詳細は重要です!)。
- ここで興味深い部分があります。スクリプトをほぼ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"
また、8〜11行目に、Xcodeがスクリプト用に設定するさまざまな環境変数の使用方法を示します。行を追加して他のターゲットのinfo.plistを編集し、メインアプリとそのヘルパーのバージョンを同期させることができます。GitHubにアクセスし、プロジェクトをダウンロードして試してから、ニーズに合わせて調整します。Xcodeによるハッピー自動バージョン管理。