カンムを支える技術 ~モバイルアプリ編~

カンムのCTOの伊藤です。

カンムではバンドルカード、そしてこれからリリース予定の pool https://pool-card.jp/ においても React Native を採用しています。 実際にどういった環境で開発運用をしているかについて簡単にご紹介します。

React Native の採用理由や経緯については React Native Matsuri 2021 で話したこちらの記事も参考にしてみてください。

speakerdeck.com

基本的な構成技術

  • React Native
  • Redux
  • Flow
  • Storybook
  • Firebase

開発の進め方

普段の開発は GitHub でタスク管理をし、PR を出してレビューするという一般的なスタイルです。 GitHub Projects を利用して進捗を管理していたり、他のチームに今後のリリースに含められる予定のものを共有する目的でアプリのリリースごとにマイルストーンを作成しています。

言語

言語はバンドルカードに関しては JavaScript + Flow 、pool は TypeScript を採用しています。 エコシステムの充実度や新しく入ってくるメンバーの経験などの理由からバンドルカードも TypeScript へ移行したいと考えています。

ビルド・リリース周り

ビルドやリリースに関しては基本的に fastlane で完結させ、それを Bitrise にて実行しています。二段階認証を使用しているApple Developerアカウントと連携することができるのでBitriseを選択しています。

App Store Connect 2FA solved on Bitrise | Bitrise

開発版の社内への配布は DeployGate を利用しています。

CI に関しては社内の既存のリソースとの兼ね合いで、テストや lint などは CircleCI を利用しています。

f:id:kanmu-tech:20211002143621p:plain

アプリのリリース自体はおおよそ週1のサイクルで行っており、コードフリーズをして必要なQAを行ってというサイクルで進めています。

API連携

バンドルカードにおいては、JSON Hyper-Schema から API クライアントの実装を自動生成しそれを利用しています。 バックエンドのAPIサーバーも同じスキーマからリクエスト/レスポンスの構造体やバリデーション実装を自動生成しています。 pool では OpenAPI を採用していますが、基本的にはバンドルカードと同様にクライアント・サーバーどちらもそのスキーマから自動生成しています。

テスト

ロジック部分のテストには Jest を利用しています。すべてを網羅できているわけではありませんが基本的に新規作成する際はテストを追加していくようにしています。
コンポーネントのテストに関しては Snapshot testing を行い、意図しない差分が出ていないかを確認しています。 E2E テストに関してはアプリのフローに SMS 認証が挟まる都合上実現できておらずどのように解決するかを模索中です。

Storybook

いわゆるUIコンポーネントカタログのような使い方をしています。デザイナーも Xcode を使用してアプリをビルドすることで Storybook を参照できるようにしており、いつでも実際の実装を確認することができます。Storybook を起動してもらう際にアップデートなどで様々なトラブルが発生しますが所持していない端末で確認できるようになったので結果的には良かったと思っています。
ライトに確認できるように将来的には社内用に独立したアプリとしてビルドしておきたいと考えてはいます。
使い回さないページなどのコンポーネントも全て Storybook 化しており、これに対して Snapshot testing を行っています。

エラートラッカー/クラッシュレポート

エラートラッキングには Sentry を利用しています。定期的に発生しているエラーをトリアージして issue に転記しながら優先順位をつけて随時対応していっています。 合わせて Firebase Crashlytics も利用しており、Firebase で記録しているイベントに紐付けられて便利なので Sentry の補助的な役割として使っています。

Firebase の他の機能

アプリの行動ログは Firebase Analytics で収集しています。react-navigation の遷移イベントをフックにページ遷移のトラッキングなどもしています。 他には Remote Config を A/B テストや、その他任意のタイミングで文言を切り替えたい場合などに利用しています。

その他

Expo は使っていないか?

バンドルカードを開発した当初 Expo はなかったためそのまま使用せず開発しており、必要に応じてモジュール単位で使用しています。

自前の Native Module はどのくらいあるか?

バンドルカードにおいて、スクリーンショットの制御周りと、ローカル認証の制御のためにすごく小さな Native Module 2 つ管理しています。 ネイティブの機能をゴリゴリ使いたいような類のアプリケーションではないので Native Module を書く機会はかなり少ないです。

おわりに

こう振り返ってみるとかなり素朴な構成でここまでやってきております。 長年運用してきている中での課題も色々見えて来ているというのが現状で、やりたいことは無限にあります。

カンムでは React Native で開発するエンジニアもそうでないエンジニアも絶賛募集しております

kanmu.co.jp