きりかノート 3冊め

おあそびプログラミング

XcodeのテンプレートのInjectionTargetsについて説明するよ

"【iOS】 Xcode開発Tips初級編その2 -プロジェクトテンプレートを自前で作ってみる- - @kitano_ow 's blog"

ただ、この場合、自前テンプレートを選択すると、強制的に入ってしまうので ARCのように、チェックがあったら利用するとかそのような形にできればと模索中です。

に反応。去年のCocoa勉強会でちょうどそこらを調べたのです。ということで、実際にログのマクロを使うかどうかをチェックボックスで指定できるようにしたテンプレートを作ってみましょう。

ポイント

  • 既存のテンプレートに機能の追加をするには"InjectionTargets"を使う。
  • 追加機能の有効無効を指定できるようにするには"Options"を使う。

の2点を押さえておけばおっけー。

詳しくは昨年9月の発表資料「Xcode 4のプロジェクトテンプレート」を見てください。このときは、MacのアプリケーションテンプレートにQuartzCoreフレームワークのリンクを追加するかどうかを選べるようにする、という機能を追加してみました。

作成例

TemplateInfo.plistを作成していきます。

Identifierを設定します。アプリケーションと同様、ユニークになるようにする必要があります。

   <key>Identifier</key>
   <string>jp.nifty.i.kimuraw.dt.unit.AddDebugLog</string>

InjectionTargetsに今回対象にするテンプレートのIdentifierを指定します。

   <key>InjectionTargets</key>
   <array>
     <string>com.apple.dt.unit.singleViewApplication</string> <!-- iOS: "Single View Application" -->
   </array>

Definitionsに追加するコード片を記述します。これは同じですね。

   <key>Definitions</key>
   <dict>
       <key>___PACKAGENAME___-Prefix.pch:debuglog</key>
       <string>#ifdef DEBUG
   #define LOG(fmt,...) NSLog((@"%s %d "fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
   #else
   #define LOG(...)
   #endif</string>
   </dict>

Optionsでプロジェクト作成時の選択要素を追加することができます。

   <key>Options</key>
   <array>
     <dict>
       <key>Identifier</key>
       <string>OWDebugLog</string>
       <key>Name</key>
       <string>Use "LOG()"</string> <!-- display text at side of this option -->
       <key>Description</key>
       <string>Whether use "LOG()" or not</string>
       <key>Type</key>
       <string>checkbox</string>
       <key>SortOrder</key>
       <integer>5</integer> <!-- display order of options -->
       <key>Default</key>
       <string>false</string> <!-- note: Xcode suggests previous selection -->
       <key>Units</key>
       <dict>
         <key>true</key>
         <!-- "true" -> merge the following settings into the new project -->
         <dict>
           <key>Nodes</key>
           <array>
             <string>___PACKAGENAME___-Prefix.pch:debuglog</string>
           </array>
         </dict>
       </dict>
     </dict>
   </array>

Options下のdictそれぞれが選択要素となり、さらにその中は

  • Identifier: 識別子です。他とかぶらないようにします。
  • Name: 名前的にまぎらわしいですが、実際に画面に説明としてこちらが表示されます。
  • Description: ツールチップとして表示されます。
  • Type: checkboxの他に、popupやtextがあるようです。
  • SortOrder: 表示順を決めます。
  • Default: 初期値を設定しますが、2回目以降はXcodeが前回選択した値を初期値として提示します。
  • Units: keyの値のとき、その内容がテンプレートにマージされます。

のようになっています。実際の標準のテンプレートを見てみると理解が進むと思います。また、DefinitionsをUnitsの中に書くこともできます。選択結果によってコード内容が複雑に変わる場合などはそのようにしたほうが良いでしょう。

これらを含む.xctemplateを作成し、~/Library/Developer/Xcode/Templates/Project Templates/Applicationに配置します。すると、

のように、"Single View Application"にチェックボックスが追加されます。これをチェックして新規プロジェクトを作成すると、

ログのマクロが追加されたプロジェクトが作成できます。もちろん、チェックボックスをオフにして作成したプロジェクトではマクロは追加されません。

できあがったTemplateInfo.plistをgistに上げておきます。

次の手順ですぐに試せると思います。

   % mkdir -p ~/Library/Developer/Xcode/Templates/"Project Templates"/Application/Application+owdebuglog.xctemplate
   % curl https://gist.github.com/kimuraw/5373058/raw/0be72c8d87e38751be218fa5907eec115b816118/TemplateInfo.plist -o \
   ~/Library/Developer/Xcode/Templates/"Project Templates"/Application/Application+owdebuglog.xctemplate/TemplateInfo.plist

おまけ

"InjectionTargets"と複数形になっていることからもわかるように、複数指定することができます。

たとえば、gistに貼ったものではコメントアウトした"com.apple.dt.unit.cocoaApplication"を有効にすると、Macの"Cocoa Application"のプロジェクトテンプレートでも同じ機能を使うことができます。場合によっては便利かもです。