【atte FeSセミナーレポート②後編】「楽に速く開発できるように」…ソウゾウのiOSエンジニア石川氏が「メルカリ アッテ」の設計と開発フローを紹介

メルカリのグループ会社であるソウゾウは、地域コミュニティアプリ「メルカリ アッテ」のリリースを記念して、2週連続月曜日にアッテリリースまでの裏側を語る「atte FeS」を先日完成したばかりのオフィス新イベントスペースで開催。本稿では、2週目の開催となる「Go・Swift開発編」について紹介する。今回はその後編で第三部の模様をお伝えしよう。

attefes203
メルカリのグループ会社であるソウゾウは、地域コミュニティアプリ「メルカリ アッテ」のリリースを記念して、4月11日・4月18日の2週連続月曜日にアッテリリースまでの裏側を語る「atte FeS」を先日完成したばかりのオフィス新イベントスペースで開催。

ソウゾウは、2015年9月、メルカリのグループ会社として、「Building next ordinary(ありそうでなかったをソウゾウする)」をミッションに設立された会社。3月17日より、地域コミュニティアプリ「メルカリ アッテ」を提供している。

イベントは、以下のような構成であった。本稿では、2週目の開催となる4月18日(月)の「Go・Swift開発編」について紹介する。本サイト「Pedia News」では、イベントの模様を前編・中編・後編に分けてお伝えしたい。今回はその後編で第三部の模様をお伝えしよう。

* 第一部 アッテ開発の技術:Golang と Google Cloud Platform
* 第二部 アッテ開発の技術:Swift と RxSwift
* 第三部 アッテ開発の技術:アッテの設計と開発フローの変遷

### 開発後半からジョイン
第三部では、「アッテ開発の技術:アッテの設計と開発フローの変遷」と題して、ソウゾウのiOSエンジニア石川洋資氏が登壇。石川氏は、面白法人カヤック、LINEを経て2016年2月にソウゾウへ入社。Swiftの言語機能を活かした型安全なネットワークライブラリAPIKitの開発者。2016年3月にはtry! Swiftに登壇。

冒頭、石川氏は、

普段から設計を考えることが好き。開発の後半に入ってきたエンジニアだが、設計を考えながら変えてきた。開発の後半に入ってきたエンジニアがどこに着目してどのように設計を変えてきたかを話したい。

と述べた。

### 「同じ構造の実装の一元化」
まず石川氏は、「同じ構造の実装の一元化」について、アプリ開発ではデータの操作パターンが同じものが多いと述べた上で、典型的な例として、

* ページネーション
* フォームのバリデーション

を紹介し、

「同じ構造」を担当するのはMVVMでいうところのViewModelが担当する。MVVMはMVCからは遠くなくて、UIViewControllerのうち表示ロジックをViewModelに分けたという仕組み。Viewの中にUIViewControllerがあり、そこからUIイベントをViewModelに送り、ViewModelがモデルに対してリクエストを送る。そうすると、モデルからレスポンスが返され、ViewModelからViewに表示値が返されてストリームで自動的に反映される。ViewModelは表示ロジックを担当するので、Viewは他のパーツにすり替えられるようになっている。

と述べた。

### 「アッテ」のページネーション
石川氏によれば、「アッテ」でページネーションを利用しているところは、タイムライン、いいねリスト、メッセージ、通知、コメントで、多くのデータを表示する場所で利用しているとのこと。

石川氏は、「アッテ」の「ページネーション」について、

MVVMの場合、タイムラインのViewControllerがあると、それに対応したタイムラインのViewModelがあり、そのタイムラインのViewModelがAPIクライアントとやり取りをしてタイムラインViewControllerが表示するためのデータを整えて渡す。ページネーションのデータ管理はViewModelが担当するが、愚直にやると画面ごとにそれぞれ実装する必要がある。そこで、「アッテ」では抽象化して、ページネーションの普遍的なところをジェネリックに記述し、表示するエレメントを型パラメーターで渡して特殊化させることにした。

と説明した。

石川氏は、「アッテ」の実装を振り返り、「ページネーションで何を型パラメーター化するか」について、

* ページネーションのエレメント(Messeage、Notificationなど)
* ページネーションのためのリクエスト
* 表示したいエレメントとリクエストのエレメントを一致させる

を取り上げ、「型パラメータを受け取ったあとどう実装するか」について、

プロトコルで実装のための足場を用意して、ジェネリックなViewModelではプロトコルで定義したインターフェースだけを利用して実装するという方針。リクエスト側にはページネーションのパラメーターをもち、レスポンス側にはエレメントの配列や次ページの有無などのプロパティーなどをもつというプロトコルを定義している。これにより、画面固有のところだけ型パラメーターとして与えて、それぞれのViewController向けにViewModelを特殊化するということが実現できている。

と述べ、その結果、実装の一元化で開発が高速かつ安全になったことを明かした。

### 「アッテ」のキャッシュ戦略
次に、石川氏は、「アッテ」の「キャッシュ戦略」について、「アッテ」はWebAPIのクライアントでキャッシュを実装することが大切であると説明した上で、

当初のキャッシュ戦略はRealmでキャッシュを取るというものだった。つまり、レスポンスはRealmのObjectとして表現しなければならなかった。しかし、それだと何もかもRealmのObjectになってしまい、何が永続化されているのか型から判別できなくなり、削除ポリシーが複雑になり、さらにマイグレーション対象が広くなると感じていた。そこで、Realmの原点に立ち返り、①レスポンスの永続化、②画面間の変更の共有であると考え直して大きく変えた。「アッテ」はWebAPIのクライアントなので、大事な情報はサーバーに届いている。そのため、クライアントで持っているデータは捨てても良いデータで、捨てても良いものはパージ前提の機構で保存する方針に変更し、JSONをLRUディスクキャッシュに保存することにした。LRUはデータサイズが一定量を超えると使われていないものから削除するというもので、これによって削除ポリシーが明確になった。また、保存されたJSONと実行時の型に不整合があればJSONを捨てれば良いと考え、マイグレーションの心配もなくなった。さらに、レスポンスを表す型をデータベースから独立させたことによって、レスポンスを表す型の制限がなくなった。以前はObjectMapperライブラリを使っていたが、初期化した後にJSONのバリデーションのエラーが外部にも波及するという問題があった。現在はHimotokiに移行して、JSONのバリデーションと型のインスタンス化を一致させられた。これにより、不正なJSONによるエラーを局所的に留められるようになった。また、画面間の変更の共有ではグローバルなSubjectとして共有した。

と説明した。

### LRUとRealmを適材適所へ
一方で、石川氏は、今でも「アッテ」ではRealmを使おうとしていることを明かし、

サーバーに届いているデータはLRUディスクキャッシュで、サーバーに届いていないデータはRealmと使い分けている。サーバーに届いていないデータには、送信中のメッセージ・コメントや入力中のフォームなど、捨ててはいけないデータでマイグレーションする価値があるデータを含む。適材適所でLRUとRealmを使い分けている。

と述べた。

### 「アッテ」の自動デプロイポリシー
そして、石川氏は、「アッテ」の「自動デプロイ」について、

入社当初は自動ビルドという仕組みがなかった。手元でアーカイブしたくないと感じていたし、人数が増えてきたフェーズでもあったので、プルリクエストがマージされたら誰でもすぐに動作確認できるようにしたいというモチベーションがあった。その他にも、「QAが完了したらすぐに審査に出せるようにしたい」「誰かの環境に依存せずにデプロイできるようにしたい」と感じていた。そこで、Travis CIを使って自動デプロイするようにした。「アッテ」の自動デプロイのポリシーは、①git pushされたらアーカイブ+デプロイ、②ビルド番号はTravis CIが振る、③手元でのアーカイブは基本的にしない。デプロイする環境は、開発版にはデプロイゲート、ストアに出るプロダクション版にはテストフライトを利用している。また、gitブランチ毎にビルドタスクを切っており、feature: テスト、master: テスト+Development、release: テスト+Development+Productionに分けている。これにより、テストフライトで動作確認したらそのまま追加の操作なしでiTunes Connectでサブミットできる。実際に「アッテ」では、releaseブランチにgit pushしてから7分後にはiTunes Connectにあがるようになった。自動デプロイの導入で、①すぐ動作を確認してもらえるようになり、②ビルドしてくださいって言われなくなり、③申請が楽になり、④誰でも申請できるようになった。今日、デザイナーが初めてプルリクエストしてそれをマージしてすぐ動作確認できていた。自動デプロイを導入して非常に良かったと感じている。

と述べ、自動デプロイの導入で開発がより高速化・効率化し、チームのコミュニケーションをより一層円滑化したことを明かした。

### 「アッテ」の設計のポイント
最後に、石川氏は、「アッテ」の「設計のポイント」について、

* 楽に速く開発できるように設計を考えている
* ミスが起こりやす設計は避ける
* 誰でも気軽にデプロイできるようにしておく
* まだまだ発展途上

と述べ、さらなる開発フローの向上へ意欲を語った。

「メルカリ アッテ」App Store

メルカリのエンジニアブログ

メルカリ・ソウゾウの採用情報はこちら