Flutterを使って医師相談アプリを短期リリースした話

 Flutterを使って医師相談アプリを短期リリースした話

コロナ時代の医療業界を支援するエムスリーのプロダクト開発の舞台裏 にて発表
https://m3-engineer.connpass.com/event/180876/

AskDoctorsのアプリをFlutterで開発したときの話です

A87027204ff57be1dadbf36a78a73c1b?s=128

Takaki Hoshikawa

July 09, 2020
Tweet

Transcript

  1. None
  2.   • 星川貴樹 (@oboenikui) • Androidエンジニア • 2017年新卒入社 • Kotlin

    Fest 2018, 2019スタッフ
  3.   • 医師相談サービスAskDoctorsについて • AskDoctorsアプリで使われている技術の話 • AskDoctorsアプリプロジェクトの話

  4. None
  5. None
  6. None
  7. None
  8.   COVID-19に関する相談を無料で行えるように • 相談には通常有料会員登録が必要 • COVID-19関連の相談が7/9現在 5,800件以上

  9.   COVID-19の一部相談を無料公開 • 相談の閲覧も有料会員以外は通常制限あり • COVID-19関連の質問のうち一部を無料公開

  10.   テレビでも紹介! • めざましテレビで紹介されました! 家具レンタルに医師への健康相談も! ステイホームで利用者増の注 目「サブスク」

  11.   しかし

  12.   アプリがない

  13.   メンバー構成 • アプリエンジニア(私)、サーバサイドエンジ ニアはAskDoctorsチーム外のメンバーとい う強気の構成 • プロジェクトは1月スタートなのにデザイナー は4月入社というさらに強気の構成 役割

    人数 プロダクトマネージャー (メイン・アシスタント ) 2 スクラムマスター 1 アプリエンジニア 1 サーバサイドエンジニア 1 QAエンジニア 1 デザイナー 1
  14.   2019年12月 AskDoctorsアプリ 構想が持ち上がる プロジェクト 始動 2020年1月 プロジェクト状況 社会的な状況 1/16

    国内最初の COVID-19感染確認 ペーパープロトタ イプv1完成 プロジェクト承認 2月 3月 ユーザーインタ ビュー開始 2/13 東京都在住者初の COVID-19感染確認
  15.   3月 アプリ 実装開始 4月 プロジェクト状況 社会的な状況 3/20 国内累計感染者 数

    1,000人を超える アプリv1.0.0 完成 5月 6月 ユーザーイン タビュー開始 4/7 7都府県に 緊急事態宣言 5/25 東京都など 緊急事態宣言解除 デザイナー入社 4/18 国内累計感染者 数 10,000人を超える 6/18 自粛要請解除 Flutter未経験ながら 約2ヶ月で両OS実装
  16. None
  17.   ファーストビューでアプリの世界観をつかめるよう に、トップでは以下の3つに絞った • どんな相談が寄せられているのか • 相談開始 • キーワード検索

  18.   ファーストビューでアプリの世界観をつかめるよう に、トップでは以下の3つに絞った • どんな相談が寄せられているのか • 相談開始 • キーワード検索

  19.   ファーストビューでアプリの世界観をつかめるよう に、トップでは以下の3つに絞った • どんな相談が寄せられているのか • 相談開始 • キーワード検索

  20.   ファーストビューでアプリの世界観をつかめるよう に、トップでは以下の3つに絞った • どんな相談が寄せられているのか • 相談開始 • キーワード検索

  21. None
  22.   クライアント 作業するエンジニアは Androidエンジニア1人 ほぼ1コードでiOS, Android両OS対応 できるクロスプラットフォーム技術 サーバー チーム外のエンジニアが担当 Web版と重複する機能が多い

    新規でサーバをたてずに 既存プロダクトに機能追加 今日の話はこちら
  23.   • Flutter • Firebase ◦ Push通知やAnalyticsで利用 • OpenAPI ◦

    APIの提供先がこのアプリのみなのでGraphQLなどは用いず ◦ Dart向けにAPIクライアントの自動生成をしやすいのも強み
  24.   • Googleが提供する、DartのUIツールキット • 単一のコードベースからモバイル・Web・デスクトップ向けに ネイティブコンパイル可能 • OSのUI Frameworkのラッパーではなく、独自のレンダリングエン ジン上で動かす

  25.   プラットフォーム固有のコードをほぼ書かずに済む • ビジネスロジックに加え、UIもコードをほぼ共通化できる • コードを共通化してもジェスチャーナビゲーションやアニメーション が各プラットフォームで自然

  26.   プラットフォーム固有のコードをほぼ書かずに済む Android iOS

  27.   Material Designが標準 • Material DesignはAndroidエンジニアに馴染み深い • ガイドラインのドキュメントがFlutterのドキュメントとリンクし ており、コンポーネントの正しい使い方と関連付けしやすい •

    Material Designガイドラインの新コンポーネントの実装が早い
  28.   Hot reloadが爆速 • Widgetの微調整で多大な恩恵を受ける • ただし修正箇所によってはHot reloadが効かないケースもある

  29.   Hot reloadが爆速

  30.   他のプロジェクトでも使っていた • Androidエンジニアが関わる他の社内プロジェクトでも採用してお り知見共有しやすかった • 結果的に社内でクロスプラットフォームで作るならFlutterという 風潮に

  31.   Flutter導入時の疑問 • Dartってどうなの? • UI構築とかやりやすい? • ライブラリちゃんとあるの?

  32.   言語仕様はとっつきやすく、流行を取り入れてきている • Dartの言語仕様はJavaやJSに少し似ておりとっつきやすい • 例えばNull-safetyも言語仕様として導入されており今後に期待 (Flutterではまだ使えない)

  33.   Future<void> createFile(String fileName) async { try { var file

    = File('$fileName.txt'); if (await file.exists()) { var modified = await file.lastModified(); print('$fileName は既に存在します。 $modified に変更されました。'); return; } await file.create(); } on IOException catch (e) { print('$fileName を作成できません: $e'); } } より、一部改変
  34.   好きなIDEを使える・補完機能などは改善中 • 補完などの機能はdart analysis serverに委譲 (LSPも対応) 原理的に特定のIDEに依存しないので好きなエディタを使える • ラムダ式の補完がDart

    2.8 (5月リリース) で実装されるなど発展 途上ながらも、現行バージョンでも十分利用に耐えられる
  35.   Web開発に近いスタイル • 基本的にシングルスレッド・イベントループ • 文法は全く異なるが、Reactと同じく宣言的UIを採用しているので 経験があればスッと理解できそう ◦ CSSはないのでカスタマイズ性でつらいところはある

  36.   Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title:

    const Text('$_pageTitle'), ), // AppBar body: Center(child: Text('$_count 回')), floatingActionButton: FloatingActionButton( onPressed: () => setState(() => _count++), tooltip: 'カウンタ', child: const Icon(Icons.add), ), // FloatingActionButton ); // Scaffold } より、一部改変
  37.   Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title:

    const Text('$_pageTitle'), ), // AppBar body: Center(child: Text('$_count 回')), floatingActionButton: FloatingActionButton( onPressed: () => setState(() => _count++), tooltip: 'カウンタ', child: const Icon(Icons.add), ), // FloatingActionButton ); // Scaffold } より、一部改変
  38.   Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title:

    const Text('$_pageTitle'), ), // AppBar body: Center(child: Text('$_count 回')), floatingActionButton: FloatingActionButton( onPressed: () => setState(() => _count++), tooltip: 'カウンタ', child: const Icon(Icons.add), ), // FloatingActionButton ); // Scaffold } より、一部改変
  39.   Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title:

    const Text('$_pageTitle'), ), // AppBar body: Center(child: Text('$_count 回')), floatingActionButton: FloatingActionButton( onPressed: () => setState(() => _count++), tooltip: 'カウンタ', child: const Icon(Icons.add), ), // FloatingActionButton ); // Scaffold } より、一部改変
  40.   完璧にOSに寄り添ったデザイン、というのは厳しい • OSごと両方実装するのでなければ、iOS UIとMaterial Designの どちらかを選択する必要がある • Material Designを使っている人の方が圧倒的に多そうなので無難

    にやるならMaterial Designを採用した方がよさそう ◦ iOSのMaterial DesignなGoogleアプリを許せるなら問題ない
  41.   標準コンポーネントが若干拡張性に乏しい • 状態を持つWidgetの場合、継承してカスタマイズが難しい場合あり • 他にも可視性がprivateに設定されたクラスが多く、継承できない 問題は多い

  42.   ほぼSwift/Kotlinのコードを触る必要がないほどまで発展 • Flutterライブラリがある ≒ Swift/Kotlinを触る必要がない • Webサイトと同等機能を有するアプリであればライブラリを利用すれ ば困らない •

    今回使ったOpenAPI GeneratorやFirebaseもDart・Flutterに 対応
  43.   ライブラリの質は…… • かなり使われているものでも数ヶ月メンテナンスされていないライブ ラリが結構あるのが欠点 • デファクトスタンダードと呼べるものはまだ少ない • プルリクチャンスが多い

  44.   (WebViewを扱うライブラリのissueにて) Q. 「Cookie取得したいんだけどどうしたらいい?」 A. 「evalJavascript("document.cookie") で取得できるよ」 HttpOnly Cookie 取得できないじゃん

    ドメインを指定して 取得とかも厳しい
  45.   (特に)iOSのバージョンアップに追従できていないケース Androidエンジニアが作ってることが多いのか、iOSでバグることがそ れなりにある

  46.   • 新規アプリ • UIを共通化しても問題ない場合 • エンジニアのリソースが限られている場合 • OS固有の処理が少ないケース •

    機能的にはWebでも実現できるサービスのアプリ
  47. None
  48.   • デザイナーが4月入社 & 即アサイン • ペーパープロトタイプや実装はデザイナーなしでその前から着手

  49.   • デザイナーが4月入社 & 即アサイン • ペーパープロトタイプや実装はデザイナーなしでその前から着手 • デザインを凝らずにプロトタイピング &

    実装 • Material Designのガイドライン的にこうだろう、という判断で仮 決め
  50.   • Google, Apple共にCOVID-19関連アプリは基本的にリジェクト • 社内でも「感染を回避する行動を取ろう」というコンセプトのアプリ がリジェクトされまくった

  51.   • Google, Apple共にCOVID-19関連アプリは基本的にリジェクト • 社内でも「感染を回避する行動を取ろう」というコンセプトのアプリ がリジェクトされまくった • 苦渋の決断でCOVID-19無料相談の実装を削除

  52.   • いざ審査を出すとGoogleは問題なく通ったがAppleはリジェクト • 「医者が答えてる保証はあるんですか?」

  53.   • いざ審査を出すとGoogleは問題なく通ったがAppleはリジェクト • 「医者が答えてる保証はあるんですか?」 • AppStore Connectでコミュニケーションを取って医師が回答して いることの説明を数回

  54.   • Apple「アプリ外課金してますよね?」

  55.   • Apple「アプリ外課金してますよね?」 • 課金リンクを消しても、一部例外を除き有料サービスのアプリは AppStoreの課金を実装する必要あり (Netflixアプリとかそういう方針だから行けるかと ……) 関連記事: https://gigazine.net/news/20200617-apple-hey-pay-subscription/

    • アプリ内課金は現在実装中のためiOS版は未リリース……
  56.   • Android版AskDoctors使ってみてください! • Flutterはいいぞ! • 医療のコンシューマプロダクトに興味あるエンジニア募集中!!!