Xcode 11がCFBundleVersionとCFBundleShortVersionStringを$(CURRENT_PROJECT_VERSION)と$(MARKETING_VERSION)に変更しないようにする方法は?


14

バージョン11以降、ターゲット設定([全般]タブ)にバージョンまたはビルドの値を入力CFBundleVersionする$(CURRENT_PROJECT_VERSION)と、Xcodeは私の値をto およびmy CFBundleShortVersionStringtoの値に$(MARKETING_VERSION)設定します。

入力した実際のバージョンとビルド値は、project.pbxprojファイルに保存されます。ビルド時に値を変更するためにシェルスクリプトを使用するため、私はこの動作を望まない、または好きではありません。

Info.plistファイルで手動で正しい値を設定できますが、ターゲット設定でバージョン番号またはビルド番号を変更するとすぐに、Info.plistファイルがXcodeによって再び変更されます。

Xcode 11がこれを行わないようにするにはどうすればよいですか?

ビルドスクリプトを変更してプロジェクトファイル自体を変更すると、Xcodeはプロジェクトファイルが変更されるとすぐにビルドをキャンセルします。


シェルスクリプトを変更して値を取得するのではなく、Xcode 11でこれを停止するのはなぜですか?
マヌエル、

1
@Manuel私はplistを使用して変更することplistbuddyは素晴らしくてきれいだと思いますが、プロジェクトファイルを変更することははるかに面倒で、信頼できず、ファイル形式に予期しない変更が加えられる傾向があります。
Zystem氏、

1
ファイル形式を理解していれば、project.pbxprojファイルの操作は面倒ではありません。十分に文書化されているのは、単なるNextスタイルのplistです。plistbuddyを使用してファイルを変更することもできます。この形式と互換性があります。
マヌエル、

私はあなたのユースケースの提案で私の答えを更新しました。
マヌエル、

回答:


1

これまでの道

私のユースケースはそれでした:

  1. 複数のターゲット間でバージョンとビルド番号を同期しています。
  2. バージョンとビルド番号をターゲットのバージョンと同期しています Settigns.bundle
  3. CIサーバーからビルド番号を読み取って変更しています。

ポイント1と2をターゲットビルドスクリプトとして実行し、ポイント3をCI自体のカスタムスクリプトとして実行していました。

Xcodeビルド設定内でバージョンとビルドを保存する新しい方法は、スクリプトで問題を引き起こしていました。スクリプトが値を効果的に変更できなくなったためです。少なくとも読書は可能でした。

残念ながら、Xcodeがバージョンとビルド番号をプロジェクトのビルド設定に保存することを防ぐ正当な方法を見つけることができませんでしたが、回避策を講じることができました。

ビルドまたはアーカイブが作成されると、に書き込まれた値Info.plistが使用されることがわかります。これは、値がビルド時に置換されるため、同じビルド時に値を変更できないことを意味します。

またxcodeproj、cli を使用してプロジェクトを変更しようとしましたが、プロジェクトに変更を加えるとビルドが停止するため、このソリューションは機能しませんでした。

結局、私が試した多くの異なるアプローチの後で、Xcodeの新しい動作に違反していない妥協点を見つけることができました。

簡潔な答え:

ターゲット事前アクションとして、スクリプトがにそれぞれの値を書き込むに実行されるCFBundleShortVersionStringCFBundleVersion、ターゲットのにInfo.plist

真実の源として、私はの値読み取るためにXcodeのビルド設定を使用MARKETING_VERSIONしてCURRENT_PROJECT_VERSION所望の標的のを。

このように、プロジェクト設定の値を変更すると(次のビルド/アーカイブ時に)、それらの値がに書き込まれ、Info.plist既存のスクリプトロジックが引き続き機能する場合に許可されます。

詳細な回答

ビルドアクション時にリソースを変更する唯一の方法は、pre-actionスクリプトを使用することです。ビルドスクリプトから実行しようとすると、変更はすぐには有効にならず、ビルド/アーカイブの最後に存在しません。

ビルド前のアクションを追加するには、スキームの編集に移動します。

ここに画像の説明を入力してください

次に、[ビルド]および[アーカイブ]セクションを展開します。でPre-actionProvide build and settings fromドロップダウンをクリックして、値を読み取る真理値のターゲットのソースを選択します。

ここに画像の説明を入力してください

次のスクリプトを追加します。

# 1) 
cd ${PROJECT_DIR}

# 2) 
exec > Pruvit-Int.prebuild.sync_project_version_and_build_with_info_plists.log 2>&1

# 3) 
./sync_project_version_and_build_with_info_plists.sh $MARKETING_VERSION $CURRENT_PROJECT_VERSION

scripラインは次のことを行います。

  1. 同期スクリプトが実行されているディレクトリに移動します
  2. 事前アクション中にログを書き込むことを許可します。それ以外の場合、デフォルトでは出力は表示されません。
  3. MARKETING_VERSIONandを指定して同期スクリプトを実行しますCURRENT_PROJECT_VERSION

最後のステップは、提供の値を読み込み、独自の同期スクリプト記述することですMARKETING_VERSIONし、CURRENT_PROJECT_VERSIONそれぞれのターゲット/ sまでとするたびに、他のあなたが欲しいの。

私の場合、スクリプトは次のとおりです。

#!/bin/bash

#IMPORTANT - this script must run as pre-action of each target's Build and Archive actions

version_number=$1
build_number=$2

echo "version_number is $version_number"
echo "build_number is $build_number"

#update Pruvit/Info.plist
pruvitInfoPlist="Pruvit/Info.plist"
/usr/libexec/PlistBuddy -c "Set CFBundleShortVersionString $version_number" $pruvitInfoPlist
/usr/libexec/PlistBuddy -c "Set CFBundleVersion $build_number" $pruvitInfoPlist

#update Pruvit/Settings.bundle
settingsPlist="Pruvit/Settings.bundle/Root.plist"
/usr/libexec/PlistBuddy -c "Set PreferenceSpecifiers:0:DefaultValue $version_number" $settingsPlist
/usr/libexec/PlistBuddy -c "Set PreferenceSpecifiers:1:DefaultValue $build_number" $settingsPlist

#update BadgeCounter/Info.plist
badgeCounterInfoPlist="BadgeCounter/Info.plist"
/usr/libexec/PlistBuddy -c "Set CFBundleShortVersionString $version_number" $badgeCounterInfoPlist
/usr/libexec/PlistBuddy -c "Set CFBundleVersion $build_number" $badgeCounterInfoPlist

私は、共有を使用Info.plistしてSettings.bundle、私はこの一度を更新する必要がありますので、私のアプリのターゲットの両方の間。

また、私は通知サービス拡張を使用しますBadgeCounter。これは、正確に同じバージョンを持ち、それが埋め込まれているターゲットとビルドする必要があります。だから私もこれを更新します。


1

しないでください。

おそらくこの動作が変更された理由があります。その後のXcode機能がこの動作に基づいて構築される場合、状況は次第に「構築」されます。

Xcodeを曲げようとする代わりに、ビルドスクリプトがこれらの値を取得する方法を変更します。

Xcode 11の現在のアプリバージョンをスクリプトで読み取る方法

project.pbxprojファイルを操作する必要がある場合は、十分に文書化されている次のスタイルのplistです。plistbuddyこの古いフォーマットと互換性のあるものを使用できます。awkより複雑な操作がある場合は、より多くのスクリプトを使用することもできます。

私があなたのユースケースを理解している場合、で最大のバージョン番号を取得しawk、それからファイルで見つけることができるすべての低いバージョン番号を更新するスクリプトを書くことができますsed


で値を印刷するとPlistBuddy 問題なく動作するようですが、setコマンドを使用すると、project.pbxproj全体がXML .plistファイルに変換され、Xcodeで読み取ることができなくなります。例:PlistBuddy -c "Set :objects:$configurationId:buildSettings:CURRENT_PROJECT_VERSION $newProjectVersion" "$projectFile"
Zystem氏、

正確に何を実現したいかに応じて、ツールの組み合わせを使用する必要があるかもしれません
Manuel

Xcodeを再起動すると、XMLの問題が修正されました。Alsは、pbxprojファイルを変更するビルドスクリプトを実行すると、ビルドをキャンセルすることを発見しました。だからこれは本当にうまくいくわけではありません。
Zystem氏、

上記の情報で元の質問を更新しました。
Zystem氏、

1
たとえば、私のユースケースはバージョンを同期して複数のターゲット間でビルドすることです-私はバージョンを設定して最初のターゲットにビルドし、それが他のすべてに自動的に更新されるようにしたいと考えています。リソースを変更するだけなので、以前はうまく機能していました。ビルドがキャンセルされるため、ターゲットのビルドフェーズ中にプロジェクトを変更することはできません。
KoCMoHaBTa
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.