4

ここではおそらく単純なものが欠けています。XCode 4.4 でビルド番号を自動インクリメントしようとしています (TestFlight 展開の準備のため)。ターゲット上で実行され、ビルドごとに info.plist ファイルを正常に更新するシェル スクリプトが動作しています。アーカイブ用の私のビルド構成は「Ad-Hoc」という名前です。

スクリプトは次のとおりです。

if [ $CONFIGURATION == Ad-Hoc ]; then
    echo "Ad-Hoc build. Bumping build#..."
    plist=${PROJECT_DIR}/${INFOPLIST_FILE}
    buildnum=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "${plist}")

    if [[ "${buildnum}" == "" ]]; then
        echo "No build number in $plist"
        exit 2
    fi

    buildnum=$(expr $buildnum + 1)
    /usr/libexec/Plistbuddy -c "Set CFBundleVersion $buildnum" "${plist}"
    echo "Bumped build number to $buildnum"
else
    echo $CONFIGURATION " build - Not bumping build number."
fi

このスクリプトは plist ファイルを適切に更新し、アーカイブするたびに XCode に反映されます。問題は、アーカイブ プロセスから生成される .ipa ファイルに以前のビルド番号が表示されていることです。次の解決策を試しましたが、成功しませんでした。

  • ビルド前にクリーンアップ
  • ビルド前にビルド フォルダーを消去する
  • ビルド フェーズのターゲット依存関係ステップの直後にスクリプト実行フェーズを移動します。
  • プレアクションとして私のスキームでスクリプトを実行アクションとしてスクリプトを追加する

何をしても、ビルド ログを見ると、info.plist ファイルが最初のステップの 1 つとして処理されていることがわかります。これは常に、スクリプトを実行してビルド番号を更新する前に行われます。これが、ビルド番号が .ipa ファイルで最新のものにならない理由だと思います。

info.plist ファイルが処理される前にスクリプトの実行フェーズを強制的に実行する方法はありますか?

4

3 に答える 3

1

Xcode 4.4.1 では、新しいターゲットを作成し、このターゲット ビルド フェーズに「カスタム スクリプトの実行」を追加して、メイン ターゲット Plist を更新します。また、このターゲットをメインターゲットの依存関係に追加する必要があります

于 2012-08-20T11:56:50.263 に答える
1

これが発生する理由は、「スクリプトの実行」が実行されるまでに、XCode ビルド プロセスがプロジェクトの plist ファイルを既に処理して、バンドルのバージョン番号などを抽出しているためです。

XCode のログ ナビゲーター ([表示]、[ナビゲーター]、[ログ ナビゲーターの表示]) に移動し、"アーカイブ" ビルドを選択することで、これを (おそらく必要に応じてより詳細に) 確認できます。

ビルド アクションの詳細なリストがメイン ウィンドウに表示され、一番上にあるものの 1 つにProcess <projectname>-Info.plist. 右側のアイコンを使用してこれを展開すると、実際に実行されたビルド コマンドが表示されます。

これを回避する方法は、元の plist ファイルと処理されたファイルの両方を更新することでした。これにより、次のビルドではなく、現在のビルドで更新されたビルド バージョンを取得できます。

これを行うために使用するスクリプトは次のとおりです (これは Ruby です。これを使用するには、インタープリター ボックスに「/usr/bin/ruby」を入力する必要がありますが、概念はシェル スクリプトやその他のスクリプトでも同じように機能します。言語):

def incrementBundleVersion(file)
    oldVersion = `/usr/libexec/Plistbuddy -c "print :CFBundleVersion" #{file}`.strip
    components = oldVersion.split('.')
    newBuild = components.pop.to_i + 1
    version = components.push(newBuild).join('.')
    print "Updating version: #{oldVersion} -> #{version} : #{file}\n"
    system("/usr/libexec/PlistBuddy -c \"Set :CFBundleVersion #{version}\" #{file}")
end

incrementBundleVersion("#{ENV['PROJECT_DIR']}/#{ENV['INFOPLIST_FILE']}")
incrementBundleVersion("#{ENV['CODESIGNING_FOLDER_PATH']}/Info.plist")

処理されたファイルはバイナリ plist ファイルであるため、単純なテキスト ツールでは処理できないことに注意してください#{ENV['CODESIGNING_FOLDER_PATH']}/Info.plist。これを処理するには plistbuddy を使用するのが最も簡単な方法であり、テキストとバイナリ plist ファイルの両方で自動的に機能します。

于 2013-08-31T16:15:08.543 に答える
0

マーク(他)、あなたが直面しているのと同じ問題に遭遇したと思います。それを一文で説明してから説明しようと思います。

/usr/libexec/PlistBuddy を Xcode 内から実行すると、Info.plist データのキャッシュされたバージョンで動作するため、最終的にデバイスまたはシミュレーターで実行するために書き込まれるものは、必ずしも必要なものではありません。

PlistBuddyコマンドがXcode の横にある terminal.app ウィンドウで実行されます。実行されない場合、キャッシュされた値が書き込まれます。

最後に、バンドル リソースのコピー フェーズの前にバージョン情報生成スクリプトを実行し、git メッセージと自動作成される git タグに同じタグを使用して、別の実行スクリプトで変更を自動コミットすることにしました。Settings.bundle/Root.plist ファイルについては、これを毎回コミットするのではなく、「git checkout -- ${PROJECT}/Resources/Settings.bundle/Root.plist」を実行するファイナライズ スクリプトを実行することを好みました。 (これは私の存在する場所ですが、誰もが独自のシステム設定リソースファイルを置く場所ではないかもしれません).

変更をチェックし、インストール時にその一部を実行し、最後にファイナライズ スクリプトを実行するまでの間に、一部のターゲットには 6 つのスクリプトがあり、別のターゲットには 7 つのスクリプトがあります…</p>

…しかし、私にとって重要なことは、それが最終的に適切に自動化されたことです…そして、Xcode内で処理されるときに、PlistBuddyが私のplistファイルに対して行っていることを回避します。

于 2012-12-04T11:02:37.303 に答える