clusterのAndroidアプリ開発状況の紹介

# はじめに
この記事は[クラスター Advent Calendar 2020](https://qiita.com/advent-calendar/2020/cluster)の20日目の記事です。
昨日は @MSA_i さんの『[非ゲーム分野でUnity Animatorの想定外の挙動を避けるために](https://qiita.com/MSA-i/items/40ba633466a9146f8eea)』でした。

個人でUnityを使ってゲーム開発（エターナル）してるんですが、未だにAnimatorは使いこなせてないので勉強になります :smile: 

# 自己紹介
[クラスター株式会社](https://corp.cluster.mu/)で、[cluster](https://cluster.mu/)のバックエンドServer（Go）とAndroidの開発を担当をしています。
今回は、clusterのアプリのワールド・イベントに入るまでの部分（以後、outroomと略します）のAndroidネイティブ化を短期間でガッと作ってリリースしたので、現状を確認して紹介しようと思います。

# Unity版のアプリをAndroidで再実装することなった経緯など

@mizoguche の記事で紹介されているので併せて読んでいただければと思います。
https://qiita.com/mizoguche/items/09719bb1ea3c3265dcdc

以下なども一応検討したのですが、不採用になった最終的な決め手は、**すでにUnityとのBridgeが発生するのでこれ以上Bridgeが増えるのは厳しそう** という理由が一番大きいと思います。
_（もっと組織が大きくなってメンバーが増えたりしたらまた判断が変わるかもしれませんが）_

- [Flutter](https://flutter.dev/)
- [ReactNative](https://reactnative.dev/)
- [Kotlin Multiplatform](https://kotlinlang.org/docs/reference/multiplatform.html)

_直接的な決め手ではないですが、自分を含めAndroid/iOSを書きたいと思ってた_ :raised_hand: _という人が多かったというのもあると思います。_

# メンバー構成
各領域に大体2人はいる感じです（大体、兼務ですが）
*レビューできる体制になっていることが大事*


> ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40887/54b10a03-7666-1ebf-f05a-d8a7450f8a6c.png)
※図がでかくなりすぎたので、ServerとWebフロントエンドの部分は省略しました

自分は元々趣味でAndroid書いてたり以前働いていた会社で多少書いていたりしたので、最新をキャッチアップしつつUnityとのBridge部分を気合で頑張るという感じでした。

ちなみに、Androidメンバーでタッグを組んでる @warabi_mochi はWebフロントエンドエンジニアから今回Android入門してめちゃくちゃ活躍して助かってます :tada: 
（詳しくは、 https://qiita.com/warabi_mochi/items/e78aae6af59f396d5dde をご覧ください）

# Unity as a Library やBridgeなどを絡めたざっくり全体構成
clusterのアプリ内では、inroomとoutroom用に2つのプロセスが動くような形になっていて、現状は基本的にoutroomからinroomを起動するだけという関係なのでかなりシンプルな構成で動いています。
_（Billingの呼び出しなどもありますがoutroomのプロセス内で完結してます）_


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40887/31950854-6c0e-3103-ae4b-93c03375e92c.png)

今後もし、inroomのprocessからoutroomのprocessにしか無い情報などアクセスする必要が出てきたら今の構成のままでは厳しいのでプロセス間通信などを実装することになりそうです :innocent: 


# module構成
流行りはもっと分割するっぽい?ですが、チームメンバーも少ないので必要最小限のシンプルな構成を意識しました。
api/app/unityLibraryの3つのmoduleのみです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40887/0c3bd08b-6750-d9b2-2941-afaa51338476.png)

- `api`: clusterのserverが[goa](https://github.com/goadesign/goa)製で[swagger](https://swagger.io/)ファイルがあるので[OpenAPITools/openapi-generator](https://github.com/OpenAPITools/openapi-generator)でKotlinのコードをジェネレートしている
- `app`: ui/viewModelなどなどapi呼び出し以外のoutroomのコードがここに全部入っている
- `unityLibrary`: UnityからExportしたモジュールで、inroomの部分


# Android部分の技術選定など
基本的には https://developer.android.com/modern-android-development?hl=ja にあるモダンな構成になるようにしました。

- Kotlin
- Lifecycle
- ViewModel
- Room
- Navigation
- databinding
- viewbinding
- 配布はAndroid App Bundle
- etc...

上記以外だと、clusterは認証に[Firebase Authentication](https://firebase.google.com/products/auth?hl=ja)を使っているので[Firebase](https://firebase.google.com/?hl=ja)系のライブラリを使っていたりします。

DIに関しては、開発初期は普通に[Dagger](https://dagger.dev/)を使っていましたが、[Hilt と Jetpack の統合](https://developer.android.com/training/dependency-injection/hilt-jetpack?hl=ja)でViewModel周りのDIをうまいことやれそうなことがわかって途中で[Hilt](https://developer.android.com/training/dependency-injection/hilt-android?hl=ja#setup)に移行しました。

あとは、わざわざ古いバージョン使うのもアレなので[Google Play Billing Library](https://developer.android.com/google/play/billing/release-notes?hl=ja)は、version 3を使うようにしました。
_コンビニ決済（PendingPurchase）対応がなかなか厄介でしたね。。。_


# Test/CI
現状は、はじめの一歩的な感じで1ミリくらいUnitTestがあります。（今度増やしていく予定です :muscle: ）

リリースまでの間は[Firebase Test LabのRoboテスト](https://firebase.google.com/docs/test-lab/android/robo-ux-test?hl=ja)を使って雑にクラッシュしないかなどをテストしてました。
outroomでユーザーの新規登録してinroomの入室まで自動でやってくれて感動しました :smile: 

# おわり
今いるメンバーでできる限りのことをやったという感じで、まだまだ改善の余地は山程あります。
引き続き開発を加速させていって、良い体験を届けていきたいとおもってます :muscle::muscle::muscle: 

明日は @xyx の「[ソフトウェアと言霊](https://qiita.com/xyx/items/de9ef2a5b1dce3c59661)」です！！！