以前"iOS勉強会議"で少しお話した内容ですが、新しいプロジェクトを整備するタイミングがあったので、ようやくまとめてみました。
例えば、
- クイズアプリでコンテンツの異なるものを別アプリとしてビルド、リリースしたい
- サーバと通信するアプリで、テスト用に接続先を切り替えたい
といった要件の実現方法です。
TargetとConfiguration
Xcodeのビルド設定には、Target, Configuration, そしてXcode4から加わったSchemeがあります。それぞれ、以下の用途で使い分けるものとします。
- Target: 例えばクイズアプリでコンテンツの異なるもの、Lite版など。別アプリとしてリリースするもの。
- Configuration: 接続先サーバの違い(開発サーバ/ステージング/本番)、デバッグ版/リリース版など。
- Scheme: TargetをXcodeで実行するときの設定で、Build, Run, Test, Profile, Analyze, Archiveの5つに固定されています。それぞれにConfigurationを1つだけ関連付けします。
つまり、ビルド設定は Target x Configurationの数だけ存在します。SchemaはXcode上でビルド等実行する場合の"つなぎ役"です。
xcconfigファイル
ビルド設定はxcodeprojのエディタで変更できますが、TargetとConfigrationの数が増えてくると管理しきれなくなります。
xcconfigファイルは、ビルド設定のうち必要なものだけをテキストファイルで記述できる仕組みで、"New File..."からひな形を作成できます。
作成したxcconfgは、プロジェクトの"Info"タグ下にある"Configuration"で、各Configurationに関連付けます。
この状態でプロジェクト設定のエディタを開くと、xcconfigに設定した内容が(Boldでないフォントで)設定されているのがわかります。
この例ではDebug.xcconfigに、
INFOPLIST_FILE = byXcconfigFile-Info.plist
と記述しています。
xcconfigの内容はデフォルト値として使用され、xcodeprojのエディタで値を個別に上書きすることもできます。上書きしたものはBoldフォントで表示されます。
尚、xcconfigに記述するキーと値は、xcodeprojのエディタで[cmd]+[c] → xcconfigファイルで[cmd]+[p]でコピペできます。
いくつか例を挙げます。
//GCC4.2 Preprocess GCC_PREPROCESSOR_DEFINITIONS = ${TARGET_NAME} DEBUG //GCC4.2 Language GCC_PREFIX_HEADER = ${TARGET_NAME}/${TARGET_NAME}-${CONFIGURATION}-Prefix.pch //Use Frameworks FRAMEWORK_SEARCH_PATHS = $(inherited) $(SYSTEM_APPS_DIR)/Xcode.app/Contents/Developer/Library/Frameworks/ $(SRCROOT)/oss_frameworks/ //Use C++ Libraries LIBRARY_SEARCH_PATHS = $(inherited) $(SRCROOT)/oss/cURL $(SRCROOT)/oss/OpenSSL $(SRCROOT)/oss/OCMock_iOS OTHER_CPLUSPLUSFLAGS = $(OTHER_CFLAGS) -I$(SRCROOT)/oss/cURL/Headers -I$(SRCROOT)/oss/OpenSSL/Headers
ポイントをいくつか。
INFOPLIST_FILE
Info.plistファイルは、Targetごとにバージョンを分けたければ使い分け、統一でよければ一本化してもいいはずです。その場合、アプリの表示名(CFBundleDisplayName)はInfoPlist.stringsに定義し、これをTargetごとに作成します。
GCC_PREFIX_HEADER
上例ではTarget x Configurationごとにpch(pre-compiled header)ファイルを定義しています。これでTargetごとに振る舞いが違う部分の制御や、接続先サーバのURIを定義をpchファイルに定義することができます。
その他のオススメ
デバッグ用に"DEBUG"、リリース用にassertを無効化する"NDEBUG"は入れておいたほうがよいでしょう。
また上にも載せていますが、スタティックライブラリ関係は設定漏れを防ぐためにも記述を一箇所に固めておくことをおすすめします。