Flutter add-to-appとは
ネイティブアプリにFlutterを組み込むことで、フルリライトなしにFlutterを段階的に導入できる仕組み。
add-to-appは、既存のiOS/AndroidネイティブアプリにFlutterを追加する方法です。ゼロから作り直すのではなく、Flutterをモジュールとして既存アプリに組み込みます。選んだ画面やフローはFlutterで描画され、アプリの残りの部分はネイティブのまま残ります。
チームはadd-to-appを使って、アプリを段階的にFlutterへ移行したり、自分たちのプロダクトの中でFlutterが機能することを実証したり、新機能を両プラットフォーム向けに一度で作ったりしています。いずれの場合も、ネイティブアプリのリリースを止める必要はありません。
既存アプリにFlutterを追加する仕組み
ユーザーにとっては、何も変わりません。同じストアページから入手した同じアプリを使い続け、Flutterの画面もアプリ内の他の画面と同じように見え、同じように動作します。新たに何かをインストールしたり、アカウントを移行したりする必要はありません。
チームにとっては、Flutterが通常のリリースの一部に加わります。ネイティブ開発者とFlutter開発者が同じプロダクトに同時に取り組み、1回のリリースで両方の種類の画面をリリースできます。だからこそ、1つの画面や1つの新機能から始めて、そこから広げていけるのです。
計画しておくべきなのは、2つの世界が接する部分です。Flutterの画面そのものを作るのは、見通しの立てやすい作業です。労力の大半は、ネイティブとFlutterの部分を1つのプロダクトとして振る舞わせることに費やされます。画面間の遷移、ログイン中のユーザーなどのデータ共有、そして決済や分析など、アプリがすでに依存している連携機能を両側で動かし続けることです。
アプリを書き直せばいいのでは?
大規模なエンタープライズアプリのフルリライトには、大きなリスクと長い時間が伴います。UIの移植は作業の一部にすぎません。何年分ものエッジケース、ビジネスロジック、プラットフォーム固有の連携、そしてコードベースの中にはあっても誰の頭の中にも残っていない組織的な知識を、すべて実装し直す必要があります。私たちの経験では、どちらの道を選んでもその知識は掘り起こす必要がありますが、書き直しの場合は何かをリリースする前にそのすべてを掘り起こさなければならず、ローンチも全か無かの勝負になります。その間もネイティブアプリのメンテナンスと改善は続けなければなりません。書き直しの最中だからといって、ビジネス側が機能のリリースを止めることはできないのです。
add-to-appなら、既存のネイティブアプリの中にFlutterの画面を直接組み込めます。機能ごとに段階的にアプリを移行し、先に進む前にすべてを本番環境で検証できます。とはいえ、add-to-appが自動的に安全な選択になるわけではありません。ネイティブコードにドキュメントがなく、もはや誰もオーナーシップを持っていない場合は、書き直しのほうがリスクの低い道になることもあります。書き直しを選ぶべきだったケースについては、私たちが見てきたパターンを参照してください。
add-to-appをFlutterのPoCに使う
add-to-appは、手早くプロトタイプを動かすためにも使えます。ネイティブアプリの1つまたはいくつかの画面をFlutterの画面に置き換え、どの程度通用するかを確かめるのです。ステークホルダーに2台のスマートフォンを渡しましょう。1台は現在のネイティブアプリ、もう1台はFlutter add-to-appを組み込んだアプリです。画面がピクセルパーフェクトに作られていれば、違いは見分けられないはずです。Flutterに懐疑的なステークホルダーとの議論も、たいていこれで決着がつきます。
add-to-appの主要用語
どのadd-to-appプロジェクトでも、次の5つの用語が登場します。
- ホストアプリ - Flutterを追加する先の、既存のiOS/Androidネイティブアプリ。アプリの起動処理を引き続き担い、当初はメインのナビゲーションも担当します。
- Flutterモジュール - 単体で実行するのではなく、組み込まれることを前提に作られたFlutterプロジェクト。Dartコードを含み、ホストアプリのビルドの一部になります。
- Flutterエンジン - Dartコードを実行し、FlutterのUIを描画するランタイム。add-to-appプロジェクトでは、複数のエンジンを同時に動かすことがよくあります。
- ネイティブコンテナ - Flutterを表示するネイティブのコンポーネント。Androidでは
FlutterActivityまたはFlutterFragment、iOSではFlutterViewControllerです。 - ネイティブとFlutterの境界 - ネイティブコードとFlutterが接するすべての箇所。ナビゲーション、共有データ、ネイティブSDKの呼び出しなどです。