iOSアプリでのフィーチャートグル利用について調べてみた

ABテストの運用を始めたり、フィーチャーブランチ(機能ブランチ)の運用で課題を感じた際にフィーチャートグルで対応できるかもしれません。

フィーチャートグル(機能トグル、フィーチャーフラグ)のSaaSで有名な[LaunchDarkly](https://launchdarkly.com/)を試してみました。

# フィーチャートグルとは
gitでのフィーチャーブランチでの開発の進め方とは別に、フィーチャーフラグによって機能管理する手法です。

ソースコードに乖離が発生する前にmasterに積極的に機能offの状態でマージしていこうぜ、と。

中〜大規模な機能ブランチが並列で走り、マージ/リベース時に苦しんだ事はありますでしょうか。
誰かが1ヶ月前に行ったリファクタがマージされ自分のリファクタ対象ファイルがそもそも無くなっていた事はありますでしょうか。

そうではなくて機能offの状態で細かくマージしていきましょうという志向。

Wikipediaの[フィーチャートグル](https://ja.wikipedia.org/wiki/%E3%83%95%E3%82%A3%E3%83%BC%E3%83%81%E3%83%A3%E3%83%BC%E3%83%88%E3%82%B0%E3%83%AB)の説明が分かりやすいです。

> 継続的リリースと継続的デプロイは、コーディングについてのフィードバックを開発者たちに頻繁に提供してくれる。これを実現するには、複数の開発者たちのコードを可能な限り早期に統合することが必要になる。
機能ブランチはこの過程に抜け道を作ってしまう。機能トグルを利用すれば、開発者たちはメインのトラックに頻繁にソースを統合しつつも、開発中の機能へ入っていける実行経路のトグルを「OFF」にしておけば、その機能は「死んだ」状態になる。新しい実行経路を有効にするための労力は、単にトグルを「ON」に設定するだけなので、十分に小さい。

カナリアリリース。
> 機能フラグの別の利点は、カナリアリリースである。

そしてこれは銀の弾丸ではありません。

> マーティン・ファウラーは機能トグルは最後の手段であるべきとして、機能トグルを利用する前に次のような手段を検討すべきと述べている。
機能を小さく分割して段階的にリリースしていく方法
新機能へのエントリーポイントとなるUIを最後に作る方法

[Pete HodgsonさんのFeature-togglesが面白かったので翻訳してみた](https://qiita.com/TsuyoshiUshio@github/items/51c6662cd45bded95389)
フィーチャートグルの具体的な使用法について記事翻訳。非常にありがたい。

# LaunchDarklyのサンプルiOSアプリを動かしてみる

[LaunchDarkly](https://launchdarkly.com/)

![スクリーンショット 2017-12-07 23.48.07.png](https://qiita-image-store.s3.amazonaws.com/0/63205/46fa9598-82b0-596a-4142-05aa66874442.png)

30日間の無料試用があるのでサインアップ。

### ログインするとダッシュボード画面。

<img width="1334" alt="スクリーンショット 2017-12-08 15.34.43.png" src="https://qiita-image-store.s3.amazonaws.com/0/63205/6f1f9c73-6bc4-8c89-9745-d591d8ce29b4.png">

### 早速テスト用のFeatureFlagを登録

CRAATE FEATURE FLAG + ボタンをクリックし

<img width="1073" alt="スクリーンショット 2017-12-08 15.12.05.png" src="https://qiita-image-store.s3.amazonaws.com/0/63205/4728fcc9-80a3-b146-f362-9a2069cc17b7.png">

各種情報を入力して SAVE FLAG。

<img width="752" alt="スクリーンショット 2017-12-08 15.13.09.png" src="https://qiita-image-store.s3.amazonaws.com/0/63205/80263d32-327c-b83a-2f36-095207b82e52.png">

できました。

<img width="1083" alt="スクリーンショット 2017-12-08 15.13.48.png" src="https://qiita-image-store.s3.amazonaws.com/0/63205/e3c0281b-3345-fed0-550a-6ac43f338d1b.png">

### Account settings の開発用コードをメモっておく

<img width="1068" alt="スクリーンショット 2017-12-08 15.11.16.png" src="https://qiita-image-store.s3.amazonaws.com/0/63205/e4b1ae41-4e24-bf8d-3c85-0c3f90b6d1d6.png">

### サンプルアプリダウンロードし実行する

[LaunchDarkly SDK for iOS (Swift)](https://github.com/launchdarkly/hello-ios-swift)

pod install。

先ほどメモした開発者コード部分を書き換えます。

```swift:AppDelegate.swift

    // Enter your mobile key here: Account Settings -> Your Projects -> Production/Test -> Mobile key.
    private let mobileKeyTest = ""

(中略)

    private func setUpLDClient() {
        let userBuilder = LDUserBuilder()
        userBuilder.key = ""

        let config = LDConfig(mobileKey: mobileKeyTest)
        config.streaming = true

        LDClient.sharedInstance().start(config, with: userBuilder)
    }
```

```swift:ViewController
    // Enter your feature flag name here.
    fileprivate let featureFlagKey = "new-search-bar"
```

出ました！

<img width="554" alt="スクリーンショット 2017-12-08 15.41.12.png" src="https://qiita-image-store.s3.amazonaws.com/0/63205/b30399b1-5a1a-51db-1cbb-6e94156d80ba.png">

### フラグ値を変えてみる

アプリを起動したまま、WebのDashboardから値を変更してみます。

<img width="1069" alt="スクリーンショット 2017-12-08 15.41.30.png" src="https://qiita-image-store.s3.amazonaws.com/0/63205/c4722ed7-b904-5a2b-521f-d0d10f83b74a.png">

<img width="384" alt="スクリーンショット 2017-12-08 15.41.38.png" src="https://qiita-image-store.s3.amazonaws.com/0/63205/dcef5781-4999-aa83-dac0-40a199aa5f1e.png">

即時に変更されました。
これはSDKでStream受信しているからです。

<img width="554" alt="スクリーンショット 2017-12-08 15.41.46.png" src="https://qiita-image-store.s3.amazonaws.com/0/63205/439fd041-c85c-4a62-9638-a753002aba89.png">



# 雑感
割りと前から存在する技術/概念だけれど、来年以降もう少し流行る予感。
自分はこれまで使った事がなかったけれど既に使っている企業では今更感があるかもしれぬ。

ルール無しに使うとカオスになる予感。
知見が溜まったら共有します。

Apple審査通過しリリース後に大きな機能をonにするような運用するとアプリ毎停止されるはずなので注意しましょう。

toBアプリやtoBサービスで[○○社向けカスタマイズフラグ]などクライアントの名前が付いたフラグが登場してくると、開発複雑度が激増し崩壊の匂いがしてくる。
が、これはそういったカスタマイズフラグではないと声を大にして言いたい。

# 参考
- [フィーチャートグル](https://ja.wikipedia.org/wiki/%E3%83%95%E3%82%A3%E3%83%BC%E3%83%81%E3%83%A3%E3%83%BC%E3%83%88%E3%82%B0%E3%83%AB)

- [Feature Toggles (aka Feature Flags)](https://martinfowler.com/articles/feature-toggles.html)

- [Pete HodgsonさんのFeature-togglesが面白かったので翻訳してみた](https://qiita.com/TsuyoshiUshio@github/items/51c6662cd45bded95389)

- [Comparators―比べてみればわかること 第3回　ブランチvs.フラグ](http://gihyo.jp/dev/serial/01/comparators/0003)

- [LaunchDarkly](https://launchdarkly.com/)