超効率化外伝: xcconfigの便利なところ＆設定例

先日10年ぶりに帰省した時の話をしよう。

実家に着いた直後、出迎えてくれた母は初孫達との初対面を喜ぶも束の間『15分で支度しな』的な事を言い放ち、我々一行を自身のバイト先の卓球場へと拉致した。
気がつくと、初孫達は母の熱い卓球指導を受けていた。

超スピードとかそんな野暮なものでは断じてない。
母は、息子家族の歓迎とアルバイト業を効率的に処理したのである。

----

※本記事は、後半から[Automatically manage signingとxcconigで超効率化](http://qiita.com/rotors123/items/a015ff0c3c3ed3cf5c47)の補足記事にもなっています。併せてお読み頂くと幸いです。

----


# "xcconfig"とは？

正式名称は「Configuration Settings File」。
その名の通りXcodeで使える便利な構成設定ファイルであり、「.xcconfig」がファイルの拡張子となる。

なぜかApple公式のリファレンス群に解説が見当たらない為、積極的に利用して欲しくない理由でもあるのかしら？と勘ぐりたくなるが、恐らく単に解説に割く労力を割愛しているのではないかと思う。

# なぜxcconfigを使うのか？（ターゲット利用の弱点）

少し複雑な構成のプロジェクトや量産などの必要がある際に、圧倒的な利便性を発揮する。

例えばまず、Xcodeには「ターゲット（TARGETS）」という概念があり、これを利用することで「個々のターゲットに対して、プロジェクトのビルド設定とは異なる設定を行う」ことが可能だ。

参考: [Apple Developer - Xcode Overview]( https://developer.apple.com/jp/documentation/ToolsLanguages/Conceptual/Xcode_Overview/CreatingApps/WorkingwithTargets.html)

- 接続先を変更したアプリを社内向け、ストア向けのアプリとして別々に作りたい
- 大元は共通のソースで管理したい
- その他、外部ライブラリ等と組み合わせてhogehogeしたい

そういった需要には、このTARGETSやScheme、Workspace等を組み合わせる事でかなり多彩な設定ができるだが、いくつか、割と大きな弱点が存在する。

- ターゲット向けの設定はXcodeのGUIでしか設定できない
- ターゲットを複製・編集する手順が煩雑（「元ターゲット名 copy」や「元ターゲット名 copy-info.plist」などをいちいち修正しなければいけない）
- コピー元のターゲットに変更が生じた場合、コピー先のターゲットにもUIで手動で行わなければいけない
- それぞれのターゲットの差分が分かりづらい

以上のような理由から、ターゲットの数が増えると管理し辛く、設定ミス等が起こりやすくなるのである。

これらの問題をスタイリッシュに解決する一つの方法が、xcconfigだと考えて欲しい。
また、今回は紹介しないが、設定ファイルがプレーンテキストである事を利用し、ビルド前にスクリプトを流すような仕掛けを入れる事で、例えばbuild番号などを自動的に繰り上げるなどの効率化も可能だ。

# 作り方と使い方

雛形の作り方は、エディタを用いてプレーンテキストで用意しても良いし、XcodeのFileメニューから
    「New」-「File…」から「Configuration Settings File」を選択
…としてプロジェクトに追加するだけである。

<img width="991" alt="Configuration Settings File.png" src="https://qiita-image-store.s3.amazonaws.com/0/187895/f5fadf6d-d238-af8e-68f6-9d510c032392.png">

<img width="453" alt="スクリーンショット 2017-08-08 16.24.19.png" src="https://qiita-image-store.s3.amazonaws.com/0/187895/0a4d3ac1-5854-735a-0c6b-27ec05a968c3.png">

雛形はコメント以外何も書かれていない状態となっているので、これに記述例などを参考に漢らしく手書きで書いていくか、Xcodeの**Build Settingsの項目自体をエディタにドラッグアンドドロップ**（またはcmd+c/vでコピペ）して、貴方好みの設定値に変更していくのだ。

「ドラッグ」する項目（例: Info.plist files）
<img width="666" alt="スクリーンショット 2017-08-08 16.33.57.png" src="https://qiita-image-store.s3.amazonaws.com/0/187895/c40c030d-3700-5349-bcf5-6db21746a44e.png">

「…アンドドロップ」したエディタの状態。
<img width="443" alt="スクリーンショット 2017-08-08 16.33.39.png" src="https://qiita-image-store.s3.amazonaws.com/0/187895/e2ed6b76-1760-330b-2adc-a90851f9f4db.png">

最後に、Xcodeの[対象プロジェクト]-ConfigurationsでConfiguration（Debug/Release等）ごとにxcconfigを割り当てる事で有効になる。

<img width="792" alt="スクリーンショット 2017-08-08 16.55.36.png" src="https://qiita-image-store.s3.amazonaws.com/0/187895/f775f046-6df0-2f55-8b86-a186a096822d.png">

図は、「HybridModel」ターゲットのDebug/Release両方に「massprotest03（.xcconfig）」を割り当てた例。


# 記述例

※ ここから先は[Automatically manage signingとxcconigで超効率化](http://qiita.com/rotors123/items/a015ff0c3c3ed3cf5c47)を読んだ前提で記述します。

比較がしやすいよう、パターン1と2を用意した。

まず、パターン1を見て欲しい。Automatically manage signingを利用しない場合は、7項目の割り当てをdebug、releaseそれぞれに割り当てる必要がある。
次にパターン2、Automatically manage signingを利用した例。
上記とほぼ同様の設定を半分以下（3項目）かつdebug、release共通で実現しており、管理も非常にシンプルとなる。

## パターン1: 手動割り当て例（Automatically manage signing 利用なし）

```txt:Config.debug.xcconfig
//
//  Config.debug.xcconfig
//  HybridDemoSwift
//

// バンドルID
PRODUCT_BUNDLE_IDENTIFIER = hoge.hoge.hogehoge

// プロダクト名／表示名
PRODUCT_NAME = アプリ名称

// 開発チームID
DEVELOPMENT_TEAM = XXXXXXXXXX

// プロビジョニングプロファイル設定
PROVISIONING_PROFILE_SPECIFIER = hoge-dev
PROVISIONING_PROFILE = xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

// プロビジョニング向け証明書
CODE_SIGN_IDENTITY[sdk=iphoneos*] = iPhone Developer: hoge hoge (XXXXXXXXXX)

// アイコンasset
ASSETCATALOG_COMPILER_APPICON_NAME = hoge-AppIcon
```

```txt:Config.release.xcconfig
//
//  Config.release.xcconfig
//  HybridDemoSwift
//

// バンドルID
PRODUCT_BUNDLE_IDENTIFIER = hoge.hoge.hogehoge

// プロダクト名／表示名
PRODUCT_NAME = アプリ名称

// 開発チームID
DEVELOPMENT_TEAM = XXXXXXXXXX

// プロビジョニングプロファイル設定
PROVISIONING_PROFILE_SPECIFIER = hoge-appStore
PROVISIONING_PROFILE = yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy

// プロビジョニング向け証明書
CODE_SIGN_IDENTITY[sdk=iphoneos*] = iPhone Distribution: HOGE Co., Ltd (YYYYYYYYYY)

// アイコンasset
ASSETCATALOG_COMPILER_APPICON_NAME = hoge-AppIcon
```

## パターン2: 自動割り当て例（Automatically manage signing 利用あり）

```txt:Config.xcconfig
//
//  Config.xcconfig
//  HybridDemoSwift
//

// バンドルID
PRODUCT_BUNDLE_IDENTIFIER = hoge.hoge.hogehoge

// プロダクト名／表示名
PRODUCT_NAME = アプリ名称

// アイコン用asset
ASSETCATALOG_COMPILER_APPICON_NAME = hoge-AppIcon
```

パターン1、2で共通のポイントは「PRODUCT_NAME = アプリ名称」。
これは、ターゲット設定のDisplay Nameを「$(PRODUCT_NAME)」と設定しておく事で、**アプリアイコン下の文字の指定までxcconfigの記述で実現する**為の仕掛けとなる。

![hoge.png](https://qiita-image-store.s3.amazonaws.com/0/187895/070ba40c-09c0-e0bc-e692-b9477f25dcbd.png)

※現状、xcconfig側でDisplay Nameが指定できない問題の回避策。

あとは必要な数だけxcconfigを用意しておき、ビルドする際に[対象プロジェクト]-Configurationsで切り替える事で、ターゲットを切り替えることなく、簡単にビルド設定を切り替える事が可能となるはずだ。

以上。良い旅を！

## バージョン情報
Xcode：8.３.3