こんにちは、@tomorrowkey です。 STORES CRMモバイルチームで STORES ブランドアプリ の開発しています。 STORES ブランドアプリ とは、お商売をしているオーナーさんごとにオリジナルアプリを作り、お客様へのクーポンの配布やお店からのご案内をとおして、双方にとってよい関係性を築いていくためのサービスです。
ブランドアプリ開発に携わって1年になったので、その間の取り組みをまとめることで、ブランドアプリの開発ってどういうことをしているの?ということをお見せしたいと思います。
1年前のブランドアプリ
入社当時のブランドアプリを技術的な側面で振り返ってみると次のような特徴がありました。
- 😄 Full Kotlin
- 😄 Android Archtecture
- 😄 Coroutine
- 😄 No RxJava
- 😄 LiveData
- 😡 Flowなし
- 😡 Jetpack Composeなし
- 😡 Material Design 1
- 😡 CIなし
- 😡 DIなし
- 😡 静的解析なし
- 😡 テストなし
目につくところがたくさんありますが、いくつかのポイントについて書いていこうかと思います。
この1年でやったこと
CIの整備
まず特に致命的だと感じたのが、CIがないことです。
ブランドアプリはサービスの特性上スケールするほどにアプリの数が増えていきます。ということは成長とともに、リリースのコストがだんだん上がっていくことになります。それにも関わらず手作業でのリリースはコストやリスクも抱えることになるので、今後の機能開発を加速していきたいという思いからも早急に対応が必要でした。
iOSアプリと足並みを揃え、どういったアプリディストリビューションが必要か検討し、BitriseでPRごとやPRがマージされたタイミング、リリースフローなどCIが自動的にやってくれるようになりました。
導入当初はCIの設定もアプリごとにしていましたが、現在ではリポジトリ統合によってかんたんな設定の追加だけでCIの設定も自動的に行われるようになりました。
Shopify連携
効率化だけしていてもサービスとしての価値はあがらないので、目に見える部分の開発も平行して続けていかなくてはなりません。 この1年間での大きな機能開発といえば、Shopify連携があります。
www.st.inc www.st.inc www.st.inc
アプリのなかで商品を閲覧、購入できるようにするためには、WebViewの高度な制御が必要で、テクニックが求められる機能開発でした。
CRM モバイルチームではいくつかのアプローチの検討を経て、WebViewのステート管理にステートマシンを使うことで、開発の効率化と保守性の向上をはかりました。
昨年末にShopify連携がリリースされたときに開発された機能ですが、その後の機能改修においても保守性を維持しつつ開発を続けられています。
Jetpack Compose導入
入社当時はすべて AndroidView + View Bindingで作られていましたが、これから主流になるJetpack Composeの導入をしました。
いきなりすべてのAndroid ViewをJetpack Composeに置き換えることはリソース的に難しいので、単純な画面追加のタイミングでJetpack Composeの導入をして、いつでもJetpack Composeが使えるようにしました。
いまでは、画面の開発があるときにJetpack Composeに書き換えるスタイルで移行をすすめています。
Jetpack Composeの導入と共にFlowも一緒に導入しました。
リポジトリ統合
従来はアプリごとにリポジトリを分けていましたが、ライブラリ側の更新があったときの反映作業や、ビルドツールの更新だけでも大変な負荷になってきたので、リポジトリを1つにするように統合しました。
次の記事はiOSの事例ですが、Androidではマルチモジュールを駆使して複数アプリを1つのプロジェクトで扱えるようにしています。
テストと静的解析の導入
ブランドアプリのプロジェクトにはテストが存在していましたが、CIがないこともあり定期的に実行されている状態ではありませんでした。それによってテストコードとプロダクトコードの乖離が起こっており、単純にテストを実行しても、そもそもコンパイルエラーになるといった状況でした。
すべてのテストを修正したうえでCIを走らせることができればベストだったのですが、「テストが書ければ安心感があるのにな」と思うシーンは多くあったので、テストが実行される環境を用意することを優先してプロダクトコードに追いつけることが難しいコードはスキップや削除しました。
それ以降、テストを書くことで効率的にコードを書けるシーンがいくつかあり、このアプローチは正解だったなと感じています。
テストと似た観点ですが、Lintを使った静的解析もCIで走らせるようになりました。
常にテストや静的解析のお世話になっているわけではありませんが、うっかり変なコードを紛れ込ませることがなくなったので、大胆な変更もだんだんできるようになってきました。
細かいルーティンワークの効率化
この1年ブランドアプリの開発を続けてきて感じているのは、「いかに普段のルーティンワークを効率化して機能開発に集中するか」ということです。
とはいえ効率化に全力を尽くしてはサービス成長には繋がりにくいので、バランス感覚が大切だと考えています。
2度3度やるなと思う作業はドキュメント化やスクリプト化することによって、積極的に効率化するように心がけています。
今のブランドアプリ
この1年間の改善をとおしてどこが変わったのか見てみると、次のように変わりました。
- 😄 Full Kotlin
- 😄 Android Archtecture
- 😄 Coroutine
- 😄 No RxJava
- 😄 LiveData
- 😄 Flowあり
- 😄 Jetpack Composeあり
- 😡 Material Design 1
- 😄 CIあり
- 😡 DIなし
- 😄 静的解析あり
- 😄 テストあり
この1年間を通してだいぶ改善をすすめられました。
1年前では新しいアプリを作るにも1週間ほどかかっていたコストも、いまでは半日ほどまで短縮 できました。
しかし、まだ古いフレームワークを使っている部分があったり、改善できたポイントも満足いくところまでできたかというとそういうわけではありません。
これからも改善を続けていく必要があります。
今後の動き
この1年で特に機能開発を円滑にすすめていくための開発基盤を整えてきました。
本当はもっと改善できるポイントがいくつもあるのですが、新規のオーナーさんへの導入や新機能の開発など平行しながら徐々に改善をすすめていっています。
STORES ブランドアプリのモバイルアプリ開発は、そういった開発基盤を整えることがビジネス要件からも重要なポイントとなっています。
ただアプリを作るだけでなく、「どうやったらスケールするアプリづくりができるか」と考えることが好きな方がいらっしゃいましたら、ぜひ一緒にモバイルアプリ開発をしましょう。