Bonfire iOS #7 参加報告(簡単な内容のまとめや感想など)

2020年1月7日に開催されたBonfire iOS #7へ参加させていただき
その際の内容の簡単なまとめと感想を書かせていただきます。

後から資料を見直して補足したり
私見も混ざっているので
間違っている箇所や誤解している箇所があるかもしれません。
もし何かございましたらご指摘いただけますとうれしいです🙇🏻‍♂️


# ヤフーアプリの品質向上戦略

## 発表者

西 麻扇さん
[@mao_nishi](https://twitter.com/mao_nishi)

## 資料

https://speakerdeck.com/nishimao/yahuapurifalsepin-zhi-xiang-shang-zhan-lue

## 内容

ヤフーアプリが実施している品質向上戦略の中で
実際に実施した中で品質が改善した例を2つのテーマで紹介

- まずは現状把握から
- コーディング時間を増やすには

### まずは現状把握から

#### なぜ大事なのか？

まずは現状どうなっていて
それがどのように変化していくのかを計測していくことが大事だと
おっしゃっていました。

具体的には下記の点を挙げられています。

- 正しいアクションを把握するため
- ゴールが明確になることで最後まで走りきることができる
- やるべきことの優先順位をつけることができる

#### 使用しているツール

具体的な計測ツールとして
下記の２つをご紹介されていました。

- App Analytics
- XcodeのOrganizer

##### App Analytics

Appleが提供している公式のツールで
アプリのクラッシュ数などを把握することができます。

私は使用したことがなく
会場でのアンケート結果も
使用経験者は1割くらいでした。

https://developer.apple.com/jp/app-store-connect/analytics/

#### XcodeのOrganizer

XcodeのWindow > Organizerから見ることができ
こちらはアプリのクラッシュの詳細を見ることができます。

こちらも私は使用したことがなく
アンケートでも1割くらいの方が使用経験があるようでした。

実際Crashlyticsなどの方がより詳細を把握できて
便利ではないかという風におっしゃっていました。

##### Xcode11の新機能 Metrics

しかし
Xcode11からMetricsという項目が登場し
リリース済みのアプリの様々な統計情報を
取得することができるようになり
これが大変便利だとのこと。

※ ただし、取得にはユーザの許可が必要になります。

https://help.apple.com/xcode/mac/current/#/devb642b28ac

これを活用することで品質に関わる下記の項目を把握できます。

- バッテリー消費量
- 起動時間
- ハング率
- メモリ消費
- ディスク書き込み

ここでおっしゃられたことの中で
「これらが低ければ低いほどAppleは品質の良いアプリだと考える」
という言葉が個人的には印象的でした。

当たり前と言われれば当たり前なのですが
改めて言われると
「なるほどこういう点をより意識する必要があるんだな」
と思い直すことができました。


##### 【問題】アプリをまたがって一覧でデータを見ることができない

Xcode上ではアプリごとの統計を見るために
クリックして一つ一つ見なければならないのが面倒だとおっしゃっていました。

これは複数のアプリをリリースしている大きな企業ならではの悩みだなと思いました。

そこで対策として**Apple Script**を作成して一覧データを自動取得しているとのこと。

https://developer.apple.com/library/archive/documentation/AppleScript/Conceptual/AppleScriptLangGuide/introduction/ASLR_intro.html

※
詳細は作成者の
[@kazuhiro4949さん](https://twitter.com/kazuhiro494949)
がお詳しいとのこと。

ここでおしゃっていたことなのですが
各アプリのコミット数も見ているとのこと。

これはコミット数が多ければ多いほど
品質を向上させるための施策がされているのではないか
という考えからきているようです。
(人によって一つのコミットの大きさが変わってくると思うので
そこらへんのルールがあるのかちょっと気になりました👀)

##### 品質を向上させるために最終的に可視化している項目

下記の項目を可視化しているとのことでした。

![スクリーンショット 2020-01-09 4.52.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/219965/20e6d2f9-4256-95db-7b8f-9a6afff17e68.png)

この中でOSS利用数を見ていますが
Cocoapodsの使用数が多いと
Carthageの利用を推奨するようにしているとのことでした。
これはCarthageを利用することでビルド時間を削減するためです。

### コーディング時間を増やすには

#### なぜ大事なのか？

下記の点から大事だとおっしゃっていました。

- リファクタリングに時間をかけることができる
- 精神的余力が生まれる
- よくないコードを見逃さなくなる

#### コーディング時間を減らす要因

これを見た時
正直「あーこれこれ」と内心思ってしまいましたw

- バグ対応
- レビュー指摘での手戻り対応
- すり合わせMTG
- 集中力の切れた状態での稼働
- 平行開発案件がたくさんある


#### 特に平行開発案件がたくさんあると大変

この中でも
平行開発案件があることによる弊害が大きいとのことで
これを解決したことで
どういう効果があったかを紹介されていました。

##### 以前の問題

開発者がfeatureブランチを切って
開発が完了したらmasterへマージする
Github flowを利用していたとのこと。

Github flowについて
http://scottchacon.com/2011/08/31/github-flow.html
https://gist.github.com/Gab-km/3705015

これを平行開発で利用していると
各ブランチでCIを回してうまくテストが通っていたとしても
結合テスト時にうまく動作しないことにより
調査と修正という手戻りが発生してしまうことがあったとのこと。

##### 現在の方法

そこで

ブランチの廃止 + ペアプロで常時レビュー&コミット

でみんなで1つの機能を作成するようにスタイルを変更したそうです。

結果として

- 常に最終成果物でCIを回すことができる
- 常にコードレビューがされていることから手戻りが減る
- 実装完了即マージという状態でスピードが上がる

などが実現できたとのことでした。

「開発が遅くなるのでは？」
という質問をされることが多いとのことでしたが
結果的に手戻りが減るのでむしろ早くなるとおっしゃっていました。

また
開発途中のリリースに関しては
フィーチャーフラグを導入して
必要になるまでは見えないようにフラグを
立てるようにしているとのこと。

##### フィーチャーフラグについて
Googleやfacebookでも導入されている
ブランチを分けずに機能をmasterブランチへ実装していく中で
機能のオンオフを切り替えられるようにフラグを設定しておく手法です。
https://martinfowler.com/articles/feature-toggles.html

「コンフリクトが多く発生するのでは？」

という疑問が湧いたのですが、
他の方が挙げられていた質問への回答の中で

```
ストーリーで上手くやることを分けて
同じ箇所の修正が発生しないようにしている
```

と回答を聞くことができました。

私もGithub flowを利用していることが多く
featureブランチが多すぎる問題や
結合したらなぜか動かない問題などに直面した経験があり
その際にもブランチ廃止してフィーチャーフラグを導入する案も出ていたので
実際の事例が知れて大変参考になりました。

切り替えるに至った経緯や
切り替え時にぶつかった課題や解決方法など
もっと深い話が聞きたいなと思いました。

#### すべての時間をコーディングに

最後に出てきたこの言葉がとても刺さりました。

コーディングをすることで
リファクタリングの時間が得られて
アプリの品質の向上につながることに加えて

アプリについて考える時間が増えることで
より良いサービスの提供の仕方や機能などにも目を向けていくことができ
デザイナーさんや開発チーム以外の方とのコミュニケーションも活発になって
さらにアプリが良いものになっていくという相乗効果も出てくるのではないかなと
個人的には感じました。

(単純にコーディングするのが好きなので
集中してコーディングできる時間が増えるのは嬉しいことだな
という思いもあったりしますw)

# PayPayフリマ iOS

## 発表者

大西 智也さん
[@tomoya_onishi](https://twitter.com/tomoya_onishi)

## 資料

上がったら反映します

### PayPayフリマでできること

- 商品の出品
- PayPayとの連携
- ヤフオクからのリスティングなど

### iOSチーム

- 最大で10人いた
- ペアプロで開発を進めている
- iMacを使用

### ペアプロの進め方

- ディレクション1人で他は全員ペアで実装
- ペアは毎日ローテーションしている

### 開発スタイル

- [XP(エクストリームプログラミング)](https://ja.wikipedia.org/wiki/%E3%82%A8%E3%82%AF%E3%82%B9%E3%83%88%E3%83%AA%E3%83%BC%E3%83%A0%E3%83%BB%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0)

- ストーリー制
- 開発と受入れテストがセットになっていてエンジニアが開発を完了すると、ディレクションが受け入れをする
- 週1回集まって全メンバーでストーリーの確認をする。仕様の共有やどう作るかを議論する。
- TDDで一人が失敗するテストを書き、もう一人が実装を進める。ストーリーごとに役割を交代する。

### ペアプロの効果

- 属人化を防ぐ
- スキルの共有ができる
- 新卒でもペアに入るので成長が早い

### 開発の方針

- Noドキュメント
- Noコードレビュー
- Noブランチ

Noドキュメント、Noコードレビューは
ペアプロを実施することで達成できているとのことでした。

こういった仕組みで品質を担保しつつ
不要な作業を省いて常に良いスピードも保てているようです。

XPという言葉はよく耳にしていて興味がありましたが
ここまでの大きな規模で実践されている例を初めて聞き
単純にすごいなと思いました。

もっと細かく見ると
イメージとは異なった点や
そこをどう調整して取り組んでいったのかなどの話が
たくさんあると思うので
ぜひさらに深いお話を聞いてみたいなと感じました。


## リリースまでの開発の進め方

### PJ発足当初

技術的な基盤の整備

#### 背景

仕様やデザインが決まっていないなど
不確定な要素が多かったため
後々面倒になるけれども必要な

- プッシュ通知
- URLスキーム
- カラースキーム

などの仕組みの作成を行っていたそうです。

#### 開発環境構築の最強のMakefileの作成

さらに同じ時期に
誰でもコマンド一つでシミュレータが起動ができるまでの
準備をしてくれる**最強のMakefile**を作成することで
新規参入時の障壁を少なくすることができたそうです。

### 仕様が決まってきたら(デザインはできている)

APIのモックを作成し、UIの作成を進めていったそうです。

中盤以降になると、
iOSエンジニアがBFFを作成して進めている時期もあったようです。

BFFについて
https://www.atmarkit.co.jp/ait/articles/1803/12/news012_2.html

## 設計、テスト

### 設計

クリーンアーキテクチャー

### テストを書いている場所

Presenter, Repository, UseCase

### 品質を担保するためのテスト

- ペアプロでユニットテスト
- ストーリーの受け入れテスト
- リリース前にみんなでスモークテスト
- UIテストを定期実行(モンキーテスト)

この中で
ユニットテストの単位は結構細かくし
gitのpre-push時に必ずテストを通過させるようにしているとのことでした。

また
UIテストに関しては
UIの変更が多いため
あまり細かいチェックは行わず
ランダムに動かして成功すればOKくらいの単位で
実施しているとのことです。

開発の進め方を
時系列に説明して頂くことでイメージしやすく
とてもわかりやすい内容でした。

上記のような時期の違いによって
XPへの取り組み方がどう変わっていったのかなど
もっと深い話を聞いてみたいなと思いました。
(最大10名というところがちょっと気になりましたw)

# Yahoo!乗り換え案内 DarkMode対応

## 発表者

田中 達也さん
[@tanakasan2525](https://twitter.com/tanakasan2525)

## 資料
https://speakerdeck.com/tattn/yahoo-cheng-huan-an-nei-falsedakumododui-ying
https://techblog.yahoo.co.jp/entry/20191212788765/

### iOS13正式リリース日にダークモード対応

#### なぜ？

- WWDC2019に参加してAppleがダークモードにかなり力を入れていると感じ、App Storeで特集されるチャンスだと考えた
- 乗り換えアプリは日常で使用されるものなので、よりアプリに愛着を持ってもらうために好きなモードで使ってもらいたいというデザイナーさんの思いがあった

App Storeの特集という視点はなかったので
新しい気付きを得られました。
長くアプリをリリースしている方ならではの視点だなと感じました。


### 工数の見積もり

どのくらいで終わるのかがわからないため仮デザインを作成してもらい
まず対応時間を計測してあとは画面数に応じてざっくり計算

### 作業分担

1画面1Storyboardなので比較的シンプルにタスクを分けることができた。
デザイナーさんも日頃からXcodeで色設定をしていたので静的な部分は作業を割り当てることができた。

人がたくさんいらっしゃるのでタスクの分割大変なんだろうなと思いましたが
画面の設計がシンプルで切り分けやすいのは良さそうだなと思いました。
特にStoryboardのコンフリクト時の辛みはすごい感じました。。。

### Storyboardを使用していることによる決断も

Asset Catalogでライトモード、ダークモード両方を一括管理できることは便利だが
iOS11以上でないとサポートされていなかったためiOS10のサポートを切ることに。

### 画像データの作成と色の設定を同時並行で実施する

500以上の画像があり、デザイナーさんが大変。
色設定と同時並行で実施することで
負担の軽減と作業が止まることを防いだとのことです。

### バージョンの違いによる違い

iOS13SDKにした結果
iOS12以下で設定を上手く反映してくれないことが
あったようです。

- UILabelのisOpaqueがYesで背景色が未設定だとラベルが真っ黒になる
- Xib/StoryboardでAsset Catalogで色を設定している場合、コードで設定した値を上書きしてしまう

など

こういうバージョン差異は再現させるのも難しく
対策をしたら片方がおかしくなったりもぐら叩き状態になることがあるので
非常に辛いなと感じました。

## ドッグフーディングは大切

上記のような不具合は見つけづらいものですが
これを早く見つけられた要因として

社内でドッグフーディングしやすい環境を構築し
誰でもフィードバックを送れる状態にしておくこと

が大切であるとおっしゃられていました。

ドッグフーディングについて
https://makitani.net/shimauma/dogfooding

ヤフーでは
AppFeedbackというアプリを開発し
ドッグフーディング環境を構築しているとのことでした。
https://techblog.yahoo.co.jp/oss/appfeedback/

つい最近
私のチームでも作成したものに対して
フィードバックが少ないという議題が出ていたので
大変興味深かったです。

開発中は開発チームという枠内で考えがちでしたが
より多くの人が簡単に触れるようになることで
不具合の早期発見だけではなく
多くの意見が得られることでUXの向上にもつながるんだなと感じました。

普段目が向けられていなかったことだったので
多くの学びがありました。

## 新機能はエンジニアが導入を進めるべき

新機能について一番詳しいのはエンジニアのはずということ。

そして新機能を導入することで

- UXが向上してユーザは幸せ
- ユーザが増えて会社は幸せ
- 新しいことができてエンジニアは幸せ

というWin-Winの関係を構築することができる
とおっしゃっていました。

具体的には
実装してみてSlackで公開したりアプリを配布することで
開発者以外の人も興味を持ってくれて導入が促進される
とようです。

ここはまさにその通りだなと思いました。

全体を通して
体験に基づいた発表はすごいリアルで
自分も対応した時にこんなことが起きるんだろうなということが
イメージできてとてもわかりやすい内容でした。
また、周りを巻き込むための取り組みなども大変参考になりました。

# コードを書きながら同時に設計していくためのiOSアプリ開発方針

## 発表者

林 和弘さん
[@kazuhiro494949](https://twitter.com/kazuhiro494949)

## 資料
https://speakerdeck.com/kazuhiro4949/kodowoshu-kinagaratong-shi-nishe-ji-siteikutamefalseiosapurikai-fa-fang-zhen

### 今回の内容について

今回の内容は
2019年12月のアドベントカレンダーに
記載した記事を元にされていたようです。

https://techblog.yahoo.co.jp/entry/20191202785270/

#### 記事の要点

実現したいこととして

- 実際の実行結果を触りながら、心地よく動くコードを試行錯誤して書く
- ユニットテストを頻繁に実行しながら、実装を固めていく

それを実現するまでの課題として

- 一回のユニットテスト実行が無視できないほど遅い
- アプリが動いているプラットフォームの実際の挙動を完全には把握しきれない
- 成果物の最終的な仕様は作りながら決まっていき、リリース後も変化してしまう

そしてこれを解決する方法として

- 実装の試行錯誤で動くようになったプロダクトコード(動いていればOK)
- ユニットテストのテストケース(簡単にテストが書けていればOK)
- ベースとなっているプラットフォームの作りが変更に対応しやすくなっていればOK

という正しい設計の判断基準があれば良いのではないかという内容が書かれています。

### 上記を踏まえての提案

今回の発表では
下記の3つを提案されています。

- システムフレームワークを中心に必要に応じて設計していく
- ユニットテストを設計の良し悪しの評価にする(テストの書きやすさ)
- レイアードアーキテクチャは使わない


全体として
強調されてた点としては

将来的にも仕様は変わっていくものなので
最初にかっちりと設計を固めるのではなく
変更に対応できるように最低限守ることは守り
変更に応じて設計も簡単に変更できるようにしておく

ということなのかなと個人的には感じました。

そして変更に対応しやすい設計を積み上げていくためにも
テストを作成し、テストが簡単に書けるように保っていくことが
正しい設計ができている判断基準とする

ということも強調されていたのかなと思っています。

### 提案の背景

#### システムフレームワークを中心に

##### iOS SDKを使ったUIのライフサイクル

iOS SDKのUIの画面遷移、ライフサイクル、アニメーションなどは
システム側で複雑に制御されているため
そのためロジックを切り出して自前で制御をしようとすると
オブジェクトやイベント管理が複雑になってしまう。

#### iOSアプリでのユニットテストはだんだん遅くなる

ユニットテストを実行するには

アプリターゲットのビルド->テストターゲットのビルド->ユニットテストの実行

というサイクルが必要。

その中で
型推論を多く用いたり
コードの依存関係が複雑になるにつれて
ビルド時間が長くなったり

非同期テストが多いことや
システム側のライフサイクルに合わせなければいけないケースが多く
一つの関数としてテスト単体化することが難しい。

#### 現実のプロダクトでは複雑なクラス設計に時間を費やせない

上記のような要因から

- 心地よくアプリを作って維持すること
- ユニットテストを必要十分に作って維持すること

は難しいとおっしゃっていました。


### 下記のシンプルな方針で進めていく

そこで
開発が進む(コードが大きくなる)につれて
下記の3つのことを順に考えていくのがシンプルで良いのではないかとのこと。

- ViewとViewControllerでクラス分割
- DIによる集約
- Embedded Frameworkによるモジュール分割

#### ViewとViewControllerでクラス分割

複雑なことは考えずに
UIKitを活用してメモリ管理などはシステム側に任せてしまう。

ロジックが複雑になってきたら
Container ViewControllerなどを利用して
そこの部分だけを切り出していく。

実装の流れとしては

```
ルートVC上はに動くコードをベタ書き
↓
ロジックが増えてきたらユニットテストを実装
↓
ロジックが複雑になってきてテストケースが複雑になったらVCやViewに分ける
```
とし

**全体を規定するアーキテクチャは導入しない**
ことを強調されています。

最初から型にはめてしまうのではなく
あくまでUIKitを中心に考え
ユニットテストの複雑さを基準にして
必要になったらモデルに切り出していく。

この進め方が良いのではとおっしゃっていました。

ここはテスト駆動開発の

レッド->グリーン->リファクタリングを繰り返していく中で
最小限の設計をしていく

という考えに近いなと感じました。

#### ユニットテストのテストケースをクラス分割の判断基準にする

上記の中でも
テストケースを判断基準にして
複雑だと感じるようになったら
モデルに切り出すということに関して

逆にユニットテストが必要ない程度のものならば
クラス設計を考える必要がないのではないか
ということもおっしゃっていました。

※
ただ、全てを一つの関数にするという意味ではなく
ロジックが変わらない範囲で
プライベートメソッドやクラスへの分割は必要とのことでした。

#### DIの集約

切り出したクラスをどのように利用するかという点において
DIについて話されていました。

テストしたいロジックをまとめてクラスに切り出して
それを抽象化(プロトコル化)した上で
元の使用していたクラスに渡してあげるのが良いのでは
とおっしゃられています。

##### 依存の切り出し方

```
中で使っているオブジェクトのプロパティ化
↓
ロジックを外からDIする(外のクラスにロジックを移動させる)
↓
初期化専用クラス(いわゆるファクトリークラス)で複数のクラスを動的に集約する
```

といったことを挙げられています。

これも全て行うという訳ではなく
切り出したクラスの数によって
どこまで考えるかは判断していくのだと思います。

##### DIを行う場所

- 初期化時に渡す
- メソッドの引数として渡す
- プロパティで渡す

を挙げられています。

一般的には初期化時に渡すのが好ましいとされていますが
テストができるならば案外どこでも良いのではないかという風に
おっしゃられていました。

Storyboardを利用しているとUIViewControllerへのDIは
プロパティで行う必要が出てきたりするので(iOS12以下の場合)
そこは状況に応じてなんだろうなと私も思いました。

そこでも守るべきこととして

DIはプロトコル経由にする

ということをおっしゃられており
これはさらにクラスを切り出していった結果
モジュールに切り出す時にも変更に対応しやすくするためです。

ここでも変更への対応のしやすさを強調されているなと感じました。

また
まずテストを書ける状態にすることが大事であり
シングルトンでもひとまずDIできるようにしておき
あとからリファクタリングする
とおっしゃっていました。

動ける状態にしてからきれいな状態にする
というテスト駆動開発の考えに近いと思いました。

同時に
きれいにしながら動ける状態を作っていくと
動かせるまでの時間が長くなるので
いつまでも終わらない感覚に陥って辛くなる。。。
という経験が何度もあったことを思い返していました。

この後にもテストが書けることを中心に考え
テストが書ければシンプルな設計で良いのでは
ということを強調されていたように感じました。

DIの方法としては

```
ロジックを切り出す
↓
外から代入する
↓
プロトコル経由にする
```

というサイクルを繰り返すして
クラスを集約していくという
ルールを守っていく以外の
複雑なクラス設計などについ難しく考えなくよいのではないか
とのことでした。

以前の私も最初から設計や形を決めていくことが多く
その中でその形に実装を寄せていってしまう傾向にあり
余計な複雑さを持ち込んでしまうことが多々あったので
この考えにはすごく共感できました。

#### ユニットテストの実行サイクルを遅くしないためのEmbedded Framework

さらにクラスの分割が進んでくると
依存関係が増えてビルド時間が増えたり
テストケースが増えることで
ユニットテストの実行サイクルが遅くなる。

そこを矯正するためにも
モジュール分割(Embedded Framework)を活用していく。

ここがレイヤー化のポイントである。

ということをおっしゃられていました。

ただし
ここでもどういう形でモジュールにするのかにこだわる必要はなく

- チーム内でコンフリクトが起きない
- テストの実行や実装が複雑にならない

といった不利益が起きない範囲で考えられれば良いのでは
というようなことをおっしゃっています。

ただ
将来的にモジュール化をしていく想定で
実装上意識すべきこととして
下記のことを挙げられていました。

- クラス間の依存をできるだけ減らす
- 循環的な依存をなくす
- 継承ではなく集約(DI)でコードを使い回す
- プロトコル経由でDIする

### 最後に

フレームワークの都合などにより
最初にきれいな設計を構築してみても
アプリを心地よく作って維持することや
必要十分なユニットテストを作って維持することはとても難しい。

だからこそ必要以上に複雑に考えず
システムの仕組みに乗っかっていく中で
複雑になってきたら
クラスを分割して設計を都度見直していく。

そうすることで
心地よいUXの提供に集中できるのではないか。

というようなことをおっしゃっていました。

どうやって実装するのかに費やす時間が増えると
UXなど何を提供するのかについて使える時間は相対的に減る
ということについて改めて考えることができました。

全体を通して
とても学べることが多くあったことに加えて
共感できる点もたくさんあって
聞き応えのある内容でした。

# 全体の感想

大きな会社、そしてIT企業としては歴史のある会社として
やはりしっかりとした仕組みや開発スタイルが確立されているすごさを
感じました。

ただ、ここまで来れたのも
相当な試行錯誤が繰り返されてきた結果であり
今でもその連続なんだろうなとも感じました。

こういう仕組みや開発スタイルについて考えることが
好きなんだということに最近気がつき
どう学び、どう身につけ、どう広めていくことができるのかについて
とても興味を持っているため
学びが多く非常に充実した時間を過ごさせたと私は感じています。

今後、もっと深い経緯を聞く機会や学べる機会があれば
率先して参加したいなと思っています。

このような素敵な会を開催してくださった
運営の皆様、登壇された皆様
本当にありがとうございました😃