Swift(Xcode)でプリプロセッサを使う
Oct 19, 2017 · iosswift3
概要
Xcodeでプリプロセッサによるソースの切り替えを行う方法
ObjectiveCなどのC系の言語の場合だと、
#ifdef DEBUG
// 開発用の接続先
let server = "api.development.push.apple.com"
#else
// 本番用の接続先
let server = "api.push.apple.com"
#endif
といった感じのことをSwift
でしたい場合の方法。
なお、Xcode8以降で有効
デバッグビルドかどうかの判別
Xcode8以降の場合は、コンパイル時のフラグとしてデフォルトでデバッグビルドにはDEBUG
が付与されている
よって、
#if DEBUG
// 開発用の接続先
let server = "api.development.push.apple.com"
#else
// 本番用の接続先
let server = "api.push.apple.com"
#endif
とするだけで良い
独自の定義を使いたい場合
Build Settings
のSwift Compiler - Custom Flags
の中のActive Compilation Conditions
の中に追加する
(デフォルトでは、Debug
のConfigutationsのみにDEBUG
が入っている)
例えば、ステージング環境のConfigurations
(Staging)に専用のHOGE
を付与したい場合は、
という感じにすればOK
ビルド設定の状態
上記の様に設定した場合、以下の環境変数に設定がされる
// 一つで設定した場合
SWIFT_ACTIVE_COMPILATION_CONDITIONS = HOGE;
// 複数で設定した場合
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG HOGE";
参考・古い方法(Xcode7以前)
Build Settings
のSwift Compiler - Custom Flags
の中にはOther Swift Flags
という項目もある
ここはActive Compilation Conditions
が登場する前にシンボルを定義する際に使っていた場所である。独自の定義を追加するには-D HOGE
と設定すれば先の設定と同じ状態になる
が、ビルドの種類(デバッグとかリリースとか)に応じて切り替えをしたい場合は、より適切なActive Compilation Conditions
に統一した方が良い
#defineは使えない
Swiftでは#define
のようにソース中で定義をすることはできない
#define
は柔軟すぎて困る(上書きされたり#undef
ができてバグる)こともあるので個人的にはこれで良いと思う
ただ、開発中などでわざわざ定義を触るのも大変な時には以下の感じで逃げている
let DEBUG = true // #define DEBUG true と同義
let server: String = {
return DEBUG
? "api.development.push.apple.com"
: "api.push.apple.com"
}()
#define
との違いは値の確定がコンパイル時ではなく、実行時に行われる点であるが、判定は初回のみなのでパフォーマンスへの影響は無視できる
開発環境
- Xcode 8.3 / 9.0