モバイルアプリの技術スタック

この章ではスタメンが提供しているモバイルアプリの技術スタックを紹介します。 iOS/Androidアプリともに、プロダクトとしての価値提供のスピードを重視し、開発効率や運用効率の高くなるような技術選定を行なっています。

TUNAG

TUNAG(ツナグ)は企業がエンゲージメント経営を実践するためのプラットフォームサービスで、スタメンの創業事業でもあります。

2017年に最初のバージョンをリリースしましたが、この時点ではウェブアプリをWebViewで表示してプッシュ通知を配信するだけの、いわゆるガワネイティブアプリでした。 創業初期の限られた開発リソースの中で、なるべく早くユーザーに価値を届けるための判断です。 その後、モバイルアプリ開発体制を強化し、チャットなどの重要な機能からネイティブ化を進めています。

TUNAG受付

2022年7月にTUNAG受付というAndroidタブレットアプリをリリースしました。 これはオフィスの受付に設置してTUNAGのチャット機能を通じて社員を呼び出すことのできるアプリです。

スタメンは2022年3月に名古屋の笹島にオフィスを移転しましたが、この新オフィス(ささしまBASEと呼んでいます)での受付システムとして有志のメンバーで開発したのがこのアプリの始まりです。 それがTUNAGの導入企業様からのニーズもあったため、ブラッシュアップしてTUNAGのオプション機能として提供することになりました。

iOS/Androidアプリ共通の技術スタック

Firebase

TUNAGアプリのバックエンドはAWS+Ruby on Railsで構築されていますが、Firebaseも利用しています。

TUNAGのモバイルアプリの重要な機能の1つであるビジネスチャットにおいては、そのリアルタイム性の実現のためにCloud FirestoreCloud Messagingを最大限に活用しています。 詳細については次のブログ記事をご参照ください。

他にも、アプリの稼働状況のモニタリングのためにCrashlytics、そして社内でのテストのために App Distributionなど、機能の実現以外においてもFirebaseが活躍しています。

以下は、2022年3月時点で使用している機能一覧です。

  • Authentication
  • Cloud Firestore
  • Realtime Database
  • Crashlytics
  • Performance
  • App Distribution
  • Google Analytics
  • Cloud Messaging
  • Remote Config

リアクティブ・プログラミング

先述のとおり、TUNAGモバイルアプリのビジネスチャットではFirebaseのCloud Firestoreを使用しています。 チャットのデータが更新されると、Cloud Firestoreを介してアプリに即時配信されますが、それらをリアクティブに処理する目的でReactiveX(以下、Rxと略す)を使用しています。

No SQLデータベースであるCloud FirestoreはRDBのようなデータのジョインが得意ではないので、基本的には平坦化した状態でドキュメントを登録します。 しかし、平坦化しすぎるとそれが弊害となるケースがあるため、一部クライアントサイドでのジョインも必要となります。この場面でRxは重要な役割を担っています。

例えば、チャットのルーム一覧画面を表示する場合、自分が所属するルームの情報、そのルームにおけるユーザーの既読情報、など複数の種類のデータを組み合わせる必要があります。 また、それぞれが異なるタイミングで更新されるという前提で処理しなければなりません。 そこで、それぞれのデータの更新をRxのストリームに変換し、合成オペレータを用いてそれらのストリームを1つにまとめることでクライアントサイド・ジョインを実現しています。

リアクティブにクライアントサイド・ジョイン

iOSにはRxと同様の機能を提供するCombine という公式フレームワークがありますが、TUNAGアプリがサポートしているiOSバージョン1では利用できないため、導入には至っていません。

AndroidではKotlinの標準ライブラリKotlin FlowがRx相当の機能を持っており、TUNAGアプリにおいても、新規開発においてはRxより優先してFlowを使用しています。

WebView

TUNAGアプリはネイティブ化を進めていますが、まだまだWebViewベースの機能を中心に構成されています。 しかしながら、これらの機能はただWebViewでウェブアプリを表示しているだけではありません。 例えば、WebViewとのログイン状態の共有や、部分的にネイティブUIで実装したハイブリッド式の画面、ディープリンクなど、アプリとしてのUI/UXに近づけるように工夫を凝らしています。

CI/CD

モバイルアプリの日々の開発においては、GitHubのPull Requestをトリガーに、ユニットテストや静的解析を自動実行しています。 そして、その結果をDangerでレビュー結果としてフィードバックすることで、一定のコード品質を確保しています。

また、モバイルアプリ開発ではstable trunkパターンでコードを管理しており、下図のようなワークフローでテスト用アプリの社内配信やアプリストアへのリリースを自動化しています。

モバイルアプリ開発のワークフロー

このような継続的インテグレーション・継続的デリバリー(CI/CD)のために、CircleCIを採用しています。

iOSアプリの技術スタック

iOSアプリの開発では、常に最新バージョンのSwiftを使用するようにしています。

UIフレームワーク

iOSアプリのUI開発にはUIKitを使用しています。 UIKitではInterface Builderでビューを実装するのが一般的ですが、TUNAGではコードでビューを実装する方法を採用しています。 なぜなら、Interface Builderによるビューの実装は、既存のビューの改修コストが高いことと、複数人での開発におけるコンフリクトの解消やレビューが難しいからです。

しかしながらビューをコードで実装する場合、意図通りの見た目になっているかが確認しにくくなるというデメリットがあります。 これを解決するためにXcode 11で追加されたXcode Previewsを活用しています。 Xcode PreviewsはSwiftUIのための開発支援機能と思われがちですが、UIKitのビューをUIViewRepresentableに準拠させることでプレビューできるようになります。 また、ビューコンポーネントの状態に応じた表示バリエーションも一度に確認できることもあり、UI開発の効率が大きく向上しました。

UIKitのビューをXcode Previewsで確認する

SwiftUIについては、TUNAGアプリがサポートしているiOSバージョン1では利用できないため導入には至っていませんが、本番導入に向けて研究を進めています。

HTTPネットワーキング

HTTPネットワーキングはAlmofireを中心とし、画像の読み込みにAlamofireImage、REST APIクライアントの実装のためにAlmofireのラッパーであるMoyaを使用しています。 アプリからは様々なREST APIを使用しますが、Moyaはその仕様に沿って宣言的に実装できます。

パッケージマネージャー

TUNAGは、FirebaseやRxSwiftなど複数のパッケージを導入しているため、パッケージ(特にFirestore)のビルド時間が長く、開発効率への影響が大きいという課題がありました。 そこで、ビルドキャッシュを再利用しやすいCarthageをパッケージマネージャーとして採用しています。

このような依存パッケージのビルド時間削減のための取り組みは、次のブログ記事にまとめています。

Androidアプリの技術スタック

Androidアプリは当初Javaで開発されていましたが、2019年に全てKotlinでのリライトが完了し、以降は常に最新バージョンのKotlinで開発しています。 Kotlinへの移行により、ボイラープレートコードの多さやNull Pointer Exceptionの発生を予期しにくいといったJavaの課題が改善され、開発効率が大きく向上しました。

UIフレームワーク

Androidアプリは当初からレイアウトファイルを用いたAndroid Viewで構築してきましたが、Androidで宣言的にUIを構築できるJetpack Composeへの移行を進めていいます。 2021年8月にバージョン1.0がリリースされたのをきっかけに、新しい機能においてはComposeを積極的に使用するようにしています。

また、既存の機能を改修する際にはAndroidViewコンポーザブルで既存のViewをリアルタイムにプレビューすることで、開発効率を改善しています。

AndroidViewコンポーザブルによるプレビュー

詳細につきましては、次のブログ記事をご覧ください。

HTTPネットワーキング

HTTPネットワーキングにはOkhttp3を中心にSquare製の信頼性の高いライブラリを使用しています。 画像ローダーにはPicasso、JSONパーサーはmoshi、そして、REST APIクライアントとして Retrofit2という具合です。 Retrofit2とmoshiにより、TUNAGのさまざまなAPIも、その仕様に従って宣言的に実装できています。

DIフレームワーク

Dependency Injection(以下、DIと略す)にはKotlinのDIフレームワークであるKoinを用いています。AndroidでのDIにはDaggerを使用することが一般的ですが、Daggerと比べてDSLでシンプルに実装できることと、コード生成やリフレクションに頼っていない点からKoinを選択しました。

TUNAG受付の技術スタック

TUNAG受付アプリは新しいオフィスで利用するために開発が始まりましたが、新しい技術の検証という目的もありました。

検証した新しい技術の1つは宣言型UI開発フレームワーク(AndroidはJetpack Compose、iOSはSwiftUI)です。 受付アプリのような小さなアプリで開発の感触を掴んだことで、TUNAGの新機能開発からJetpack Composeを本格的に採用できました。 詳細は次のブログ記事をご覧ください。

もう1つはKotlin Multiplatform Mobile (KMM)というクロスプラットフォーム技術です。 これはUI以外のコードのみを共通化するので、開発コストを下げつつ、iOS/Androidそれぞれのプラットフォームに適したUIを開発できるというメリットがあります。 受付アプリでは認証やデータ取得、呼び出し処理のようなデータレイヤーをKMMで共通化できました。


脚注

1. TUNAGはユーザーのITリテラシーの幅がとても広いです。また、導入企業の全社員が業務利用するということも考慮し、2022年9月時点では最小動作環境をiOS12・Android6に設定しています。最小動作環境は年次で見直す機会を設けており、ユーザーが使用するOSバージョンの分布、他社のサポート状況など、さまざまな観点を元に判断しています。この年次判断により、2022年12月に最少動作環境をiOS13・Android7に変更することが決まりました。

results matching ""

    No results matching ""