Build 番号の自動更新スクリプトについて #cocoa_kansai

129 Views

June 21, 14

スライド概要

ツイッターを眺めていたら Info.plist の書き換えについてのお話が流れてきました。

その話題の中心にあった agvtool と、そこから派生して Build 番号を Info.plist そのものは更新せずにビルド時に細工をしてバンドルに埋め込む方法に興味を惹かれ、それについて少し深追いしてみました。特に Info.plist Preprocessor はなかなか面白い仕組みでした。どのような場面で便利に使えるかは別としまして。

※ Docswell での公開に移行する直前の Slideshare での閲覧数は 6,751 でした。

profile-image

正統派趣味人プログラマー。プログラミングとは幼馴染です。

シェア

またはPlayer版

埋め込む »CMSなどでJSが使えない場合

関連スライド

各ページのテキスト
1.

ビルド番号の更更新について ネットで教えてもらったこと • • • Info.plist  &  Run  Script agvtool Info.plist  Preprocessor EZ-‐‑‒NET  熊⾕谷友宏    @es_̲kumagai http://program.station.ez-‐‑‒net.jp/

2.

⾃自⼰己紹介 EZ-‐‑‒NET  熊⾕谷友宏   http://program.station.ez-‐‑‒net.jp/ @es_̲kumagai EZ-‐‑‒NET  IP  Phone ⾳音で再配達ゴッド ⾳音で再配達 ⾳音でダイヤル いつもの電卓 for  iPad いつもの電卓 for  iPhone

3.

書籍 • • • • • • • • • Xcode  全機能を網羅羅 プロジェクトの作り⽅方 ソースコード編集の効率率率化 ショートカットキーの紹介 オートレイアウトの使い⽅方 ローカライズの設定⽅方法 バージョン管理理の使い⽅方 ビルド設定とスキーム設定 ほか、とにかくいろいろ こんなご時世ですが ぜひ⼿手に取ってパラパラめくってみてください。 特設サイト  ̶—  http://ez-‐‑‒net.jp/sp/xcode5/

4.

話題 さて ツイッターを眺めていたところ

5.

話題 興味深いツイートが舞い込んできました。 agvtool  のお話とか。

6.

話題 話題は  @tokorom  さん  のこちらのスライド h"ps://speakerdeck.com/tokorom/agvtooldechao-­‐katukoyokubaziyoningudekimasuka  

7.

Apple-‐‑‒Generic  Versioning  Tool agvtool

8.

Apple-‐‑‒Generic  Versioning  Tool agvtool プロダクトのバージョン管理理を⾏行行えるツール Build  Settings  に関連する設定項⽬目がある

9.

Apple-‐‑‒Generic  Versioning  Tool 準備

10.

Apple-‐‑‒Generic  Versioning  Tool Current  Project  Version  を設定 Versioning  System  で  “Apple  Generic”  を選択

11.

Apple-‐‑‒Generic  Versioning  Tool 準備完了了

12.

Apple-‐‑‒Generic  Versioning  Tool あとは プロジェクトファイルのある ディレクトリで  agvtool  を実⾏行行する だけ

13.

Apple-‐‑‒Generic  Versioning  Tool バージョンの確認 agvtool  what-‐‑‒version   Current  version  of  project  $(PROJECT_̲NAME)  is: 1 プロジェクトファイル内の CURRENT_̲PROJECT_̲VERSION  が対象

14.

Apple-‐‑‒Generic  Versioning  Tool バージョンの確認(簡潔に表⽰示) agvtool  what-‐‑‒version  -‐‑‒terse   1 プロジェクトファイル内の CURRENT_̲PROJECT_̲VERSION  が対象

15.

Apple-‐‑‒Generic  Versioning  Tool バージョンの更更新 agvtool  new-‐‑‒version  2 プロジェクトファイル内の CURRENT_̲PROJECT_̲VERSION  が対象

16.

Apple-‐‑‒Generic  Versioning  Tool CFBundleVersion  も同時更更新 agvtool  new-‐‑‒version  -‐‑‒all  3 プロジェクト内の  CURRENT_̲PROJECT_̲VERSION  と 全ターゲット  の  Info.plist  の  CFBundleVersion  が対象

17.

Apple-‐‑‒Generic  Versioning  Tool 次のバージョン番号に更更新 agvtool  next-‐‑‒version  -‐‑‒all ⼩小数点以下がある場合は切切り捨てられる

18.

Apple-‐‑‒Generic  Versioning  Tool ターゲットバージョンの確認 agvtool  what-‐‑‒marketing-‐‑‒version   No  marketing  version  number  (CFBundleShortVersionString)   in  native  targets... Found  CFBundleShortVersionString  of  “1.0”  in “PROJ.xcodeproj/../PROJNAME/PROJ-‐‑‒Info.plist” Found  CFBundleShortVersionString  of  “1.0”  in “PROJ.xcodeproj/../PROJNAME/PROJTest-‐‑‒Info.plist” プロジェクト内の全ターゲットの  Info.plist  にある CFBundleShortVersionString  が対象

19.

Apple-‐‑‒Generic  Versioning  Tool ターゲットバージョンの確認(簡潔に表⽰示) agvtool  what-‐‑‒marketing-‐‑‒version  -‐‑‒terse   “PROJ.xcodeproj/../PROJNAME/PROJ-‐‑‒Info.plist”=1.0 “PROJ.xcodeproj/../PROJNAME/PROJTest-‐‑‒Info.plist”=1.0 プロジェクト内の全ターゲットの  Info.plist  にある CFBundleShortVersionString  が対象

20.

Apple-‐‑‒Generic  Versioning  Tool ターゲットバージョンの確認(最初のひとつだけ) agvtool  what-‐‑‒marketing-‐‑‒version  -‐‑‒terse1   1.0 最初のひとつを何で決めているかは不不明

21.

Apple-‐‑‒Generic  Versioning  Tool ターゲットバージョンの更更新 agvtool  new-‐‑‒marketing-‐‑‒version  2.0 プロジェクト内の  全ターゲット  の  Info.plist  にある CFBundleShortVersionString  が対象

22.

Apple-‐‑‒Generic  Versioning  Tool バージョン管理理システムと 連動できたりするらしい 詳細は未確認

23.

Apple-‐‑‒Generic  Versioning  Tool CVS  との連携機能もあるらしい defaults  write  agvtool  CVSEnabled  YES defaults  write  agvtool  CVSSubmitByTag  YES defaults  write  agvtool  CVSToolPath  PATH Subversion  との連携機能もあるらしい defaults  write  agvtool  SVNEnabled  YES defaults  write  agvtool  SVNSubmitByTag  YES defaults  write  agvtool  SVNToolPath  PATH Git  との連携機能があるかは不不明 有効にしたバージョン管理理システムへ コミットやタグ付けを連動して実⾏行行できるらしい。

24.

Apple-‐‑‒Generic  Versioning  Tool 話題のスライド中にあった VERSIONING_̲INFO_̲PREFIX Versioning  Name  Prefix 話題のスライドとは挙動が違う様⼦子

25.

Apple-‐‑‒Generic  Versioning  Tool VERSIONING_̲NAME_̲PREFIX  に “dev-‐‑‒”  を設定してみたところ  …

26.

Apple-‐‑‒Generic  Versioning  Tool ビルドエラーになりました。 ⾒見見知らぬ  “$(PROJECT_̲NAME)_̲vers.c”  ファイル内に double  型の  “dev-‐‑‒”  で始まるシンボルが定義されている

27.

Apple-‐‑‒Generic  Versioning  Tool VERSIONING_̲NAME_̲PREFIX  は CURRENT_̲PROJECT_̲VERSION  の 値を保持するシンボル名のプレフィックス として使われる様⼦子

28.

Apple-‐‑‒Generic  Versioning  Tool ちなみにこのファイルは Derived  Data  フォルダー内に 中間ファイル  (Intermediates)  として⾃自動⽣生成される

29.

Apple-‐‑‒Generic  Versioning  Tool ちなみに $(PROJECT_̲NAME)_̲vers.c  ファイルは ビルドされてアプリに組み込まれるようなので

30.

Apple-‐‑‒Generic  Versioning  Tool “extern”  すると使えたりします。

31.

Apple-‐‑‒Generic  Versioning  Tool agvtool  の設定項⽬目

32.

Apple-‐‑‒Generic  Versioning  Tool VERSIONING_̲SYSTEM Versioning  System 必ず  “Apple  Generic”  を指定 する。 CURRENT_̲PROJECT_̲VERSION Current  Project  Version バージョン番号(この値を   agvtool  で操作する) VERSION_̲INFO_̲EXPORT_̲DECL Generated  Versioning  Variables 中間ファイル内で定義される 各変数の宣⾔言の先頭に付与す るキーワード  (export  等) VERSION_̲INFO_̲FILE Generate  Versioning  Source  Filename 中間ファイルとして⽣生成する ファイル名(拡張⼦子を含む) VERSION_̲INFO_̲PREFIX Versioning  Name  Prefix 中間ファイル内で定義される 各変数に付けるシンボル名の プレフィックス VERSION_̲INFO_̲SUFFIX Versioning  Name  Suffix 中間ファイル内で定義される 各変数に付けるシンボル名の サフィックス VERSION_̲INFO_̲BUILDER Versioning  Username 未確認

33.

Apple-‐‑‒Generic  Versioning  Tool agvtool  を  Run  Script  などで使えば ビルド番号を簡単操作できるのでしょう たぶん。

34.

#ifdef  DEBUG 話は変わって 話題のスライド中にあった記載 『Configuration  で切切り替えられるおかげで #ifdef  DEBUG  を使う必要がなくなった』 それに対して  …

35.

#ifdef  DEBUG ?! Info.plist  プリプロセッサ…?

36.

Info.plist  Preprocessor Info.plist  プリプロセッサ

37.

Info.plist  Preprocessor プリプロセッサと⾔言えば コンパイル前にソースコードを整える C  ⾔言語でお馴染みの機能 Objective-‐‑‒C  でもお馴染み

38.

Info.plist  Preprocessor たとえば、こういうものたち。 #import  “MyClass.h” #define  MyClassMaxValue  1000 #ifdef  DEBUG NSLog(“Value  =  %d”,  object.value); #endif

39.

Info.plist  Preprocessor Info.plist  プリプロセッサの 有効化

40.

Info.plist  Preprocessor Preprocess  Info.list  File  を  Yes  に設定 これで  OK

41.

Info.plist  Preprocessor Build  Settings  設定だけで Info.plist  をプリプロセスする場合

42.

Info.plist  Preprocessor Info.list  Preprocessor  Definitions  に KEY=VALUE  の形式で値を定義 複数の値を設定したい場合は、 半⾓角スペースを挟んで記載する。

43.

Info.plist  Preprocessor Info.plist  の置き換えたい部分で Info.plist  Preprocessor  Definitions  で定義したキーを記載 ビルド時にキーの部分が値に置き換わる

44.

Info.plist  Preprocessor Configuration  毎に異異なる値も設定可能

45.

Info.plist  Preprocessor ヘッダーファイルを使って Info.plist  をプリプロセスする場合

46.

Info.plist  Preprocessor 1. Info.plist  Preprocessor  Prefix  File  に プリプロセスで使う  ヘッダーファイル名  を指定 2. Info.plist  Preprocessor  Definitions  に $(GCC_̲PREPROCESSOR_̲DEFINITIONS)  を指定 $(GCC_̲PREPROCESSOR_̲DEFINITIONS)  を指定することで Preprocessor  Macros  で定義した値を使⽤用可能に

47.

Info.plist  Preprocessor Info.list  Preprocessor  Prefix  File  で指定したファイルに #define  KEY  VALUE  の形式で値を定義 ここでプリプロセッサマクロを使⽤用可能

48.

Info.plist  Preprocessor Info.plist  の置き換えたい部分で Info.plist  Preprocessor  Definitions  で定義したキーを記載 ビルド時にキーの部分が値に置き換わる

49.

Info.plist  Preprocessor Info.list  Preprocessor  Prefix  File  で Info.plist  をプリプロセスする際の留留意点 値の更更新時はヘッダーファイルだけを 更更新しても  Info.plist  が更更新されない 変更更を反映するには Info.plist  ファイルの更更新が必要

50.

Info.plist  Preprocessor Info.plist  プリプロセッサーで使⽤用できる設定項⽬目 INFOPLIST_̲PREPROCESS Preprocess  Info.plist  File これを  “Yes”  にすると   Info.plist  がプリプロセスされる INFOPLIST_̲PREFIX_̲HEADER Info.plist  Preprocessor  Prefix  File プリプロセス時に使⽤用する キーと値が書かれたヘッダー ファイル名を指定(任意) INFOPLIST_̲PREPROCESSOR_̲DEFINITIONS プリプロセス時に使⽤用する キーと値を指定(半⾓角スペー スで分けて複数指定可能) Info.plist  Preprocessor  Definitions INFOPLIST_̲OTHER_̲PREPROCESSOR_̲FLAGS プリプロセッサに渡すフラグ Info.plist  Other  Preprocessor  Flags を指定(-‐‑‒DDEBUG=1  など)

51.

Info.plist  Preprocessor Based  on  Configuration  File  と合わせて使えば Info.plist  の複雑な調整もできるかも? ターゲットや  Configuration  毎に 設定内容を調整できる機能

52.

宣伝 Based  on  Configuration  File  については Xcode  5  徹底解説 9.10  Configuration  設定ファイルを使って ビルド設定をテキストファイルで管理理する をご覧下さい。

53.

話題 いつしか話は次の展開へと進み  …

54.

話題 ひとつの解が⽰示されました。 h"ps://github.com/kishikawakatsumi/BuildNumber

55.

ビルド番号の更更新についての話題の中で… 解答の中で挙げられていた 「問題点」の但し書き そこに意識識が留留まりました。

56.

Info.plist  処理理のタイミング 『Compile  Sources  より前に      Run  Script  を実⾏行行しても間に合わない』

57.

Info.plist  処理理のタイミング 『間に合わない』 ⾃自分も書籍執筆中に体験

58.

Info.plist  処理理のタイミング そのときは Info.plist  を  Run  Script  で 更更新してもビルドに間に合わない というもの

59.

PlistBuddy Info.plist  の更更新といえば /usr/libexec/PlistBuddy プロパティリストファイルを読み書きできるコマンド

60.

PlistBuddy 使⽤用例例 infoPlistFile="${SRCROOT}/${INFOPLIST_̲FILE}” buildNumber=$(/usr/libexec/PlistBuddy                -‐‑‒c  "Print  CFBundleVersion"  "${infoPlistFile}") buildNumber=$((${buildNumber%%.*}  +  1)) /usr/libexec/PlistBuddy                -‐‑‒c  “Set  CFBundleVersion  $buildNumber"  "${infoPlistFile}" Info.plist  の  CFBundleVersion  を更更新する例例

61.

PlistBuddy 【書式】/usr/libexec/PlistBuddy                                        –c  “コマンド”  “プロパティリストファイル” Print  KEY KEY  の値を出⼒力力 Set  KEY  VALUE KEY  に  VALUE  を設定 Copy  srcKEY  dstKEY srcKEY  とその値を  dstKEY  として複製 Delete  KEY KEY  とその値を削除 Add  KEY  TYPE  [VALUE] TYPE  型の  KEY  を追加(値は任意) Clear  TYPE TYPE  型の  Root  要素として初期化(TYPE   は  Array  や  Dictionary  を指定) Merge  FILE  [KEY] FILE  で指定したプロパティリストの内容を   KEY  の値として追加(KEY  の型は  FILE  の   Root  要素と同じ型のものを指定,  省省略略時は   Root  要素に追加) Import  KEY  FILE Data  型の  KEY  を作成してファイルの内容 を値として設定

62.

Info.plist  処理理のタイミング なぜ 間に合わないのか

63.

Info.plist  処理理のタイミング ビルドログを確認すると… 1 2 Target  Dependencies [1] Compile  Sources Link  Binary  With  Libraries [2] Copy  Bundle  Resources 間に合いそうに ⾒見見えるのですが…

64.

Info.plist  処理理のタイミング 今、試してみると 間に合うようなのですが  …

65.

Info.plist  処理理のタイミング 調査当時は  なぜか 間に合いませんでした

66.

Info.plist  処理理のタイミング それはさておき。

67.

Info.plist  処理理のタイミング Info.plist  プリプロセッサを有効にしたとき 1 2 Target  Dependencies Preprocess  Info.plist  File [1] Compile  Sources Link  Binary  With  Libraries [2] Copy  Bundle  Resources Preprocessed-‐‑‒Info.plist   を⽣生成して処理理する様⼦子

68.

Info.plist  処理理のタイミング Target  Dependencies  Build  Phase  の直後に Info.plist  のプリプロセスが完了了する Info.plist  のプリプロセスに必要な情報を Run  Script  Build  Phase  で揃えても間に合わない

69.

Info.plist  処理理のタイミング ただし プリプロセス済みの  Info.plist  ファイルは 従来どおりのタイミングで組み込まれる このプロジェクトの  Info.plist  ファイルは  もともと Preprocessed-‐‑‒Info.plist  だったとみなせる  かも

70.

Info.plist  書き換えの⼿手段 今回の話題のスライド中では 『Info.plist  を直接書き換えずに調整したい』 が⽬目標に掲げられていました。

71.

厳Info.plist  書き換えの⼿手段 それなら Preprocessed-‐‑‒Info.plist  を 直接  書き換えたらどうなるか

72.

Info.plist  書き換えの⼿手段 ログを⾒見見る限りでは  … * Target  Dependencies Preprocess  Info.plist  File [*] Compile  Sources [*] Link  Binary  With  Libraries Copy  Bundle  Resources Copy  Bundle  Resources  までの間 編集する猶予が得られそう

73.

Info.plist  書き換えの⼿手段 Run  Script  はこのような感じに infoPlistFile="${TEMP_̲DIR}/Preprocessed-‐‑‒Info.plist” buildNumber=$(/usr/libexec/PlistBuddy                -‐‑‒c  "Print  CFBundleVersion"  "${infoPlistFile}") buildNumber=$((${buildNumber%%.*}  +  1)) /usr/libexec/PlistBuddy                -‐‑‒c  "Set:CFBundleVersion  $buildNumber"  "${infoPlistFile}" Preprocessed-‐‑‒Info.plist  ファイルのパスは 事実から  “${TEMP_̲DIR}/Preprocessed-‐‑‒Info.plist”  と推定

74.

Info.plist  書き換えの⼿手段 更更新できました。 ビルドにも間に合う様⼦子

75.

Info.plist  書き換えの⼿手段 留留意点 Preprocess  Info.plist  File  を有効化  した状態で $(SRCROOT)/${INFOPLIST_̲FILE}  を書き換える  と 更更新が間に合わず 次回のビルドに繰り越される

76.

Info.plist  書き換えの⼿手段 ちなみに

77.

Info.plist  書き換えの⼿手段 ⼀一応は  … バンドルに組み込まれた  Info.plist  を 直接  書き換えることも可能

78.

Info.plist  書き換えの⼿手段 Run  Script  はこのような感じに infoPlistFile=“${BUILT_̲PRODUCTS_̲DIR}/                                                              ${FULL_̲PRODUCT_̲NAME}/Info.plist” buildNumber=$(/usr/libexec/PlistBuddy                -‐‑‒c  "Print  CFBundleVersion"  "${infoPlistFile}") buildNumber=$((${buildNumber%%.*}  +  1)) /usr/libexec/PlistBuddy                -‐‑‒c  "Set:CFBundleVersion  $buildNumber"  "${infoPlistFile}" これを  Copy  Bundle  Resources  よりも後に実⾏行行

79.

Info.plist  書き換えの⼿手段 実⾏行行タイミングは、ここ * Target  Dependencies Compile  Sources Link  Binary  With  Libraries [*] Copy  Bundle  Resources Run  Script Copy  Bundle  Resources  で 組み込まれた  Info.plist  を扱う

80.

Info.plist  書き換えの⼿手段 ただし、実機だと2回に1度度、 コード署名あたりでエラー  が発⽣生する様⼦子 原因は不不明

81.

Info.plist  書き換えの⼿手段 実機⽤用のビルドに限って  Build  Phases  終了了後に パッケージング  と  コード署名  が⾏行行われる様⼦子

82.

Info.plist  書き換えの⼿手段 1. Run  Script  はパッケージングの前に処理理される 2. Info.plist  が処理理されてから  Run  Script  までには デバッグシンボルを⽣生成するログのみ

83.

お詳しい⽅方へ! どの辺りが 影響しているものなのでしょう?

84.

以上、 ツイッターでの  Info.plist  の話をきっかけに 分かったことの紹介でした。