基本的な使い方
XCConfig は、Xcode のビルド設定を外部ファイルとして管理する仕組みです。
ビルド設定は次の形式で列挙できます。
BUILD_SETTING_NAME = value
条件付きの値も使えます。
ONLY_ACTIVE_ARCH[config=Debug][sdk=*][arch=*] = YES
Swift からは次のように値にアクセスできます。
let object = Bundle.main.object(forInfoDictionaryKey:key)
設定とコードの分離
アプリケーションは、設定を定数としてコードの中に保存してしまうことがあります。これは Twelve-Factor への違反です。Twelve-Factor は設定とコードの厳密な分離を要求しています。設定はデプロイごとに大きく変わりますが、コードは変わりません。
悪い例
次のコードは、定数値をコードの中に持っています。
import Foundation
#if DEBUG
let apiBaseURL = URL(string: "https://api.staging.example.com")!
#else
let apiBaseURL = URL(string: "https://api.example.com")!
#endif
環境ごとに異なる値を使うときによく見かける書き方です。これはコーディングによる設定です。 この例では apiBaseURL は単なる 1 つの値ですが、コードは本来あるべき姿よりも複雑になっています。 XCConfig を導入すれば、上記のコードを丸ごと書かずに済みます。
良い例
例えば、Debug.xcconfig と Release.xcconfig の 2 つの XCConfig があるとします。
API_BASE_URL = api.staging.example.com
API_BASE_URL = api.example.com
Swift では、値を取得してそのまま使うだけです。
guard let url = Bundle.main.object(forInfoDictionaryKey:"API_BASE_URL") else {
return
}
URLSession...
どの環境でもコードは同じままで、値だけが環境に応じて変わります。
重要な注意点
XCConfig はヘッダーファイルと同じく公開されるファイルです。バイナリパッケージの中からも見えます。認証情報や機密情報を絶対に置いてはいけません。
シークレットの管理
一般的なアドバイスとして、API キーなどの認証情報のようなシークレットを xcconfig ファイルに保存するのはやめましょう。
それでも、どうしても XCConfig でシークレットを管理する必要がある場合は、XCConfig ファイルを VCS(git、subversion など)にチェックインしなければ実現可能です。
.gitignore に(git を使っている場合)、
path/to/Release.xcconfig
path/to/Debug.xcconfig
これでも Bundle API を通じて値にアクセスできます。.env と同じような仕組みです。