環境毎に処理や設定を変更したい!
前回で環境毎に設定を変更する準備が整いました。
今回は環境毎に処理内容や設定の変更行っていきます。
1. Other Swift Flagsを設定する
コード上でTARGET毎に処理を切り替える為の設定を行います。
- 任意のTARGETを選択し、Build Settingを選択します
- 右上の検索欄にOther Swiftと入力すると条件に一致した設定が表示されます
- Other Swift Flagsの値に
-D ターゲットの名前
と入れます
- 今回は”develop”としましたが、この値は各ターゲットが認識できるのであれば何を入れても大丈夫です。
図1. Other Swift Flagsの追加
2. #if ~ #endif を使用する
環境毎に処理内容を変えたり定数の値を変えたい場合、 #ifを使っていきます。
通常のif文と異なるのは{}で条件処理のブロックを指定しないことと、#endifで終了を指定することがあります。書き方は次の通りです。
#if 条件1
条件1に一致した場合に実行されます。
#elseif 条件2
条件1とは一致せず、条件2に一致した場合に実行されます。
#else
条件1,2ともに一致しない場合に実行されます。
#endif
#ifの分岐分の終了を宣言します。
条件にはOther Swift Flagで指定したターゲットの名前を指定します。
例えばdevelop, staging, releaseの設定があるとした場合、定数が各環境毎に異なる場合は次のように記述します。
#if develop
final let url = "https://dev.opst.co.jp/v1/"
#elseif staging
final let url = "https://sta.opst.co.jp/v1/"
#else
final let url = "https://opst.co.jp/v1/"
#endif
3. User-Definedから値を取得する方法
URLの設定程度ならUser-Definedに定義しておき、必要な時点で読み込むという方法もあります。
まずはUser-Definedに定義を追加してみましょう。
1. User-Definedに追加する
- プロジェクトを開き、追加するターゲットを選択します
- +ボタンをクリックし、Add User-Defined Settingをクリックします
図2. User-Definedの追加 - User-Definedに新しい項目が追加されるので追加したい定義名を入力します
図3. User-Definedが追加された - 今回はHOST-URLと入力しました
図4. User-Defined名の入力 - 項目名を決定すると値の入力欄に移動するので値を入力します
図5. User-Defined値の入力 - User-Definedが登録されました
図6. User-Definedの確定
2. info.plistに追加する
User-Definedを登録しただけではソースコード上からはまだ呼び出せません。
info.plistからUser-Definedを指定し、ソースコード上から呼び出せるようにします。
- info.plistを開き、いずれかの項目を選択します
図7. info.plistを選択 - Keyの右橋にある+ボタン(図8で赤丸で囲まれたボタン)をクリックすると項目が追加されます
図8. keyを追加 - Keyを入力します
今回はUser-Defined名と同じにしました。
図9. keyを入力 - Valueを編集します
Key名を入力したら、右のValueをクリックすると編集状態になります
図10. valueを編集する - Valueを入力します
Use-Definedを参照するには $(Use-Defined名) と入力します。
今回は HOST_URLを参照するので $(HOST_URL) と入力しました。
図11. valueを入力する
これでコード上からinfo.plistを介してUse-Definedにアクセスする準備が整いました。
3. コード上からinfo.plistを呼び出す
コード上からは次のように呼び出します。
Bundle.main.object(forInfoDictionaryKey: "info.plistのKey")
Object型なのでString型へキャストしてあげます。
強制アンラップでもいいのですが、Key名の指定ミス等で失敗することもあるのでオプショナルバインディングでアクセスしましょう。
Bundle.main.object(forInfoDictionaryKey: "info.plistのKey") as? String
guard文を使ったり??を使ってデフォルトを指定するもの良いですね。
guard let definedValue = Bundle.main.object(forInfoDictionaryKey: "info.plistのKey") as? String else {return}
if let definedValue = Bundle.main.object(forInfoDictionaryKey: "info.plistのKey") as? String ?? ""