コロナ時代の医療業界を支援するエムスリーのプロダクト開発の舞台裏 にて発表 https://m3-engineer.connpass.com/event/180876/
AskDoctorsのアプリをFlutterで開発したときの話です
View Slide
● 星川貴樹 (@oboenikui)● Androidエンジニア● 2017年新卒入社● Kotlin Fest 2018, 2019スタッフ
● 医師相談サービスAskDoctorsについて● AskDoctorsアプリで使われている技術の話● AskDoctorsアプリプロジェクトの話
COVID-19に関する相談を無料で行えるように● 相談には通常有料会員登録が必要● COVID-19関連の相談が7/9現在 5,800件以上
COVID-19の一部相談を無料公開● 相談の閲覧も有料会員以外は通常制限あり● COVID-19関連の質問のうち一部を無料公開
テレビでも紹介!● めざましテレビで紹介されました!家具レンタルに医師への健康相談も! ステイホームで利用者増の注目「サブスク」
しかし
アプリがない
メンバー構成● アプリエンジニア(私)、サーバサイドエンジニアはAskDoctorsチーム外のメンバーという強気の構成● プロジェクトは1月スタートなのにデザイナーは4月入社というさらに強気の構成役割 人数プロダクトマネージャー(メイン・アシスタント )2スクラムマスター 1アプリエンジニア 1サーバサイドエンジニア 1QAエンジニア 1デザイナー 1
2019年12月AskDoctorsアプリ構想が持ち上がるプロジェクト始動2020年1月プロジェクト状況社会的な状況1/16国内最初のCOVID-19感染確認ペーパープロトタイプv1完成プロジェクト承認2月 3月ユーザーインタビュー開始2/13東京都在住者初のCOVID-19感染確認
3月アプリ実装開始4月プロジェクト状況社会的な状況3/20国内累計感染者数1,000人を超えるアプリv1.0.0完成5月 6月ユーザーインタビュー開始4/77都府県に緊急事態宣言5/25東京都など緊急事態宣言解除デザイナー入社4/18国内累計感染者数10,000人を超える6/18自粛要請解除Flutter未経験ながら約2ヶ月で両OS実装
ファーストビューでアプリの世界観をつかめるように、トップでは以下の3つに絞った● どんな相談が寄せられているのか● 相談開始● キーワード検索
クライアント作業するエンジニアはAndroidエンジニア1人ほぼ1コードでiOS, Android両OS対応できるクロスプラットフォーム技術サーバーチーム外のエンジニアが担当Web版と重複する機能が多い新規でサーバをたてずに既存プロダクトに機能追加今日の話はこちら
● Flutter● Firebase○ Push通知やAnalyticsで利用● OpenAPI○ APIの提供先がこのアプリのみなのでGraphQLなどは用いず○ Dart向けにAPIクライアントの自動生成をしやすいのも強み
● Googleが提供する、DartのUIツールキット● 単一のコードベースからモバイル・Web・デスクトップ向けにネイティブコンパイル可能● OSのUI Frameworkのラッパーではなく、独自のレンダリングエンジン上で動かす
プラットフォーム固有のコードをほぼ書かずに済む● ビジネスロジックに加え、UIもコードをほぼ共通化できる● コードを共通化してもジェスチャーナビゲーションやアニメーションが各プラットフォームで自然
プラットフォーム固有のコードをほぼ書かずに済むAndroid iOS
Material Designが標準● Material DesignはAndroidエンジニアに馴染み深い● ガイドラインのドキュメントがFlutterのドキュメントとリンクしており、コンポーネントの正しい使い方と関連付けしやすい● Material Designガイドラインの新コンポーネントの実装が早い
Hot reloadが爆速● Widgetの微調整で多大な恩恵を受ける● ただし修正箇所によってはHot reloadが効かないケースもある
Hot reloadが爆速
他のプロジェクトでも使っていた● Androidエンジニアが関わる他の社内プロジェクトでも採用しており知見共有しやすかった● 結果的に社内でクロスプラットフォームで作るならFlutterという風潮に
Flutter導入時の疑問● Dartってどうなの?● UI構築とかやりやすい?● ライブラリちゃんとあるの?
言語仕様はとっつきやすく、流行を取り入れてきている● Dartの言語仕様はJavaやJSに少し似ておりとっつきやすい● 例えばNull-safetyも言語仕様として導入されており今後に期待(Flutterではまだ使えない)
Future 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');}}より、一部改変
好きなIDEを使える・補完機能などは改善中● 補完などの機能はdart analysis serverに委譲 (LSPも対応)原理的に特定のIDEに依存しないので好きなエディタを使える● ラムダ式の補完がDart 2.8 (5月リリース) で実装されるなど発展途上ながらも、現行バージョンでも十分利用に耐えられる
Web開発に近いスタイル● 基本的にシングルスレッド・イベントループ● 文法は全く異なるが、Reactと同じく宣言的UIを採用しているので経験があればスッと理解できそう○ CSSはないのでカスタマイズ性でつらいところはある
Widget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text('$_pageTitle'),), // AppBarbody: Center(child: Text('$_count 回')),floatingActionButton: FloatingActionButton(onPressed: () => setState(() => _count++),tooltip: 'カウンタ',child: const Icon(Icons.add),), // FloatingActionButton); // Scaffold}より、一部改変
完璧にOSに寄り添ったデザイン、というのは厳しい● OSごと両方実装するのでなければ、iOS UIとMaterial Designのどちらかを選択する必要がある● Material Designを使っている人の方が圧倒的に多そうなので無難にやるならMaterial Designを採用した方がよさそう○ iOSのMaterial DesignなGoogleアプリを許せるなら問題ない
標準コンポーネントが若干拡張性に乏しい● 状態を持つWidgetの場合、継承してカスタマイズが難しい場合あり● 他にも可視性がprivateに設定されたクラスが多く、継承できない問題は多い
ほぼSwift/Kotlinのコードを触る必要がないほどまで発展● Flutterライブラリがある ≒ Swift/Kotlinを触る必要がない● Webサイトと同等機能を有するアプリであればライブラリを利用すれば困らない● 今回使ったOpenAPI GeneratorやFirebaseもDart・Flutterに対応
ライブラリの質は……● かなり使われているものでも数ヶ月メンテナンスされていないライブラリが結構あるのが欠点● デファクトスタンダードと呼べるものはまだ少ない● プルリクチャンスが多い
(WebViewを扱うライブラリのissueにて)Q. 「Cookie取得したいんだけどどうしたらいい?」A. 「evalJavascript("document.cookie") で取得できるよ」HttpOnly Cookie取得できないじゃんドメインを指定して取得とかも厳しい
(特に)iOSのバージョンアップに追従できていないケースAndroidエンジニアが作ってることが多いのか、iOSでバグることがそれなりにある
● 新規アプリ● UIを共通化しても問題ない場合● エンジニアのリソースが限られている場合● OS固有の処理が少ないケース● 機能的にはWebでも実現できるサービスのアプリ
● デザイナーが4月入社 & 即アサイン● ペーパープロトタイプや実装はデザイナーなしでその前から着手
● デザイナーが4月入社 & 即アサイン● ペーパープロトタイプや実装はデザイナーなしでその前から着手● デザインを凝らずにプロトタイピング & 実装● Material Designのガイドライン的にこうだろう、という判断で仮決め
● Google, Apple共にCOVID-19関連アプリは基本的にリジェクト● 社内でも「感染を回避する行動を取ろう」というコンセプトのアプリがリジェクトされまくった
● Google, Apple共にCOVID-19関連アプリは基本的にリジェクト● 社内でも「感染を回避する行動を取ろう」というコンセプトのアプリがリジェクトされまくった● 苦渋の決断でCOVID-19無料相談の実装を削除
● いざ審査を出すとGoogleは問題なく通ったがAppleはリジェクト● 「医者が答えてる保証はあるんですか?」
● いざ審査を出すとGoogleは問題なく通ったがAppleはリジェクト● 「医者が答えてる保証はあるんですか?」● AppStore Connectでコミュニケーションを取って医師が回答していることの説明を数回
● Apple「アプリ外課金してますよね?」
● Apple「アプリ外課金してますよね?」● 課金リンクを消しても、一部例外を除き有料サービスのアプリはAppStoreの課金を実装する必要あり(Netflixアプリとかそういう方針だから行けるかと……)関連記事:https://gigazine.net/news/20200617-apple-hey-pay-subscription/● アプリ内課金は現在実装中のためiOS版は未リリース……
● Android版AskDoctors使ってみてください!● Flutterはいいぞ!● 医療のコンシューマプロダクトに興味あるエンジニア募集中!!!