【iOS】アプリ開発におけるAPI環境切り分けとConfig管理

# `Target`/`Scheme` によるConfig管理

## 目指すところ

- ソースコード各所での実装が簡潔である
- `Scheme`つまりはビルド環境が開発者間、CIなどと連携できる

## 手順

前提としてAPIサーバは `開発(Development)`/`ステージング(Staging)`/`本番(Production)` があるものとする

1. 各環境ごとに`Target`を作る
2. 各`Target`ごとに`Scheme`をつくる
3. Config のインタフェースを定義する
4. 各環境ごとに Config を実装する

### 1. 各環境ごとに`Target`を作る

<img width="645" alt="スクリーンショット 2019-04-19 17.55.50.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85825/f1e63e3c-2ba0-94d8-ba5e-bf93ff689ba9.png">
<img width="571" alt="スクリーンショット 2019-04-19 17.58.04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85825/2899152b-e70f-a2d5-dbf6-7464bb96d9fa.png">

#### 余談

<img width="1184" alt="スクリーンショット 2019-04-19 17.59.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85825/70f9ebf1-8c23-13f4-1842-10ce92de0f95.png">

### 2. 各`Target`ごとに`Scheme`をつくる

`[Manage Schemes...]` から各`Target`ごとに`Scheme`を作る。

<img width="542" alt="スクリーンショット 2019-04-19 18.00.05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85825/50f11aae-e6c8-8b40-bc8b-e8d3ec4988db.png">

<img width="919" alt="スクリーンショット 2019-04-19 18.00.15.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85825/0d2cd3f9-6df0-0850-5468-31cf41731699.png">
<img width="762" alt="スクリーンショット 2019-04-19 18.00.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85825/64e1835d-da57-2822-06c7-91139682ea79.png">

`[Executable]`を各`Target`に設定。

<img width="964" alt="スクリーンショット 2019-04-19 18.00.57.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85825/254f98d4-1d7e-3d55-cb5c-7ee04e2f4dc0.png">
<img width="945" alt="スクリーンショット 2019-04-19 18.01.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85825/2e5f2057-051c-feed-8efc-86e3161d7118.png">
<img width="1003" alt="スクリーンショット 2019-04-19 18.01.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85825/2b335e05-f3e2-38dd-b75e-a1fe1368f7f5.png">
<img width="855" alt="スクリーンショット 2019-04-19 18.02.21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85825/0cbc41d4-569d-b9f2-0450-32709da4da47.png">

3環境分完了。

<img width="444" alt="スクリーンショット 2019-04-19 18.02.41.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85825/5dec372f-e22e-0bb4-b1cf-b1af128dd7d7.png">

### 3. Config のインタフェースを定義する

インタフェース = `Protocol` を定義する。

<img width="941" alt="スクリーンショット 2019-04-19 18.05.21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85825/b0471854-f5db-939a-a4f9-855fb43dc5b0.png">

```swift
protocol APIConfigProtocol {
    var baseURL: URL { get }
}

struct APIConfig: APIConfigProtocol {
    // インスタンス化させない
    private init() {}
}
```

ここではプロトコルの採用のみを行い、`var baseURL: URL`の実装は行わない。
このままの状態だとビルドエラーになるが、それが正しい。

### 4. 各環境ごとに Config を実装する

次に`Development`環境のConfig実装を行う。

<img width="901" alt="スクリーンショット 2019-04-19 18.07.07.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85825/5d66c549-7aca-f78d-e4b2-602a5da13716.png">

```swift 
extension APIConfig {
    var baseURL: URL {
        return URL(string: "https://dev.foo.com")!
    }
}
```

これをあと2環境分行う。

<img width="1389" alt="スクリーンショット 2019-04-19 18.11.55.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85825/0a069622-5b4d-c8fa-9666-68969d965db9.png">
<img width="1395" alt="スクリーンショット 2019-04-19 18.12.44.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85825/57935eea-8370-0dce-7db5-057b87d7b47c.png">

## 結果

`SampleApp Development` では `https://dev.foo.com` が返り、

<img width="918" alt="スクリーンショット 2019-04-19 18.15.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85825/da955968-3ef2-1811-a2db-680383442614.png">

`SampleApp` では `https://foo.com` が返る。

<img width="476" alt="スクリーンショット 2019-04-19 18.15.20.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85825/5ca6f435-9393-6fab-19e1-9386cb2f68f5.png">
<img width="928" alt="スクリーンショット 2019-04-19 18.15.36.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85825/c6a185d6-d627-ac7c-dea6-cd7a15ce10f3.png">