気づいてみれば、スマートフォン向けのアプリケーションを作り始めて、7年目に入りました。
前半はほとんどJavaでAndroid向けに、後半はKotlinでAndroid向けだけかと思ったら、SwiftやDartでiOS向けにも。 開発環境が増えただけでなく、開発するだけのお仕事からどう開発するか考えるお仕事も増えてきました。 *1
かつては「iOSのアプリから作る」とか「Android向けのデザインは用意するべきなのか」とか、そんな話をよくよくしていたように思います。 翻って、今のアプリ開発を見ると「ネイティブ(*)で作るべきか、クロス/マルチプラットフォームで作るべきか」なんて話が中心になったように感じています。複数のOSでどうするかって話に対して、選択肢が増えたので、OS固有の事情を割とフラットに見ている感じですね。
今回は、まずは自分の経験を棚卸しする意味で。 そして友人とアプリについて話をするために、今考えているアプリケーションの分類について書いてみます。
議論の整理のための下準備
アプリケーションの「インストール」
スマートフォンにおいて、アプリケーションが「インストール可能かどうか」は一つの大きな分割ポイントです。 今回は「ホーム画面にショートカットを置く」ことは『インストールと呼ばない』という立場をとります。 つまり、PWAのことは『インストールとは呼ばない』という立場です。
今回「インストール」と呼ぶのは、AndroidであればPackageManagerServiceを利用したケースを想定しています。 *2 このためPWAは『インストールとは呼ばない』のですが、TWAは『インストールと呼ぶ』こととなります。
描画されているViewのカタチ
デザインシステム、デザインガイドラインのことを指しています。 AndroidやiOSの場合、それぞれMaterial DesignやHuman Interface Guidelinesがあるので、イメージしやすいかなと。
なお、デザインシステムという言葉は「発する人」と「発せられている環境」で微妙な差異があるように思っています。 つまり、発しているのがデザイナー/エンジニア/ユーザーでずれが生じますし、サービスのデザイン/プロダクトのデザイン/(各プラットフォーム上の)アプリのデザインでズレがあります。 この辺りについては、以前書いたブログの頭の方で(別方向ですが)掘り下げています。
Webにおける、標準のViewについて。
例えば<input type="date">
を指定した時、ブラウザごとに見た目は異なるように、AndroidとiOSでは標準で提供されるViewのデザインが異なります。
場合によっては、機能も一致しません。
手元で確認するには、次のページを異なるブラウザで開いてみてください。
一方で、UIフレームワークを導入することでこの差をなくすこともできます。 下記のページでMaterial DesignのWeb向けのカレンダーを確認してみると、ChromeでもFirefoxでも同じ表示がされています。
AndroidやiOSの場合、それぞれのプラットフォームで推奨されるデザインシステム・ガイドラインのViewが代表的なViewになります。 ネイティブSDKを使う限り、独自にCanvasを用いたViewでも利用しなければ、代表的なViewがアプリのViewに反映されます。
一方で、Webの場合は「ブラウザのView」と「利用しているライブラリのView」が存在し、代表的なViewというものが存在しない印象があります。 利用しているデザインシステムやUIフレームワークがアプリごとに異なるため、統一した話にまとめにくい印象です。 *3
簡単なまとめ
今までの論点と、独断と偏見でまとめた各仕組みの嬉しいところをまとめてみます。
インストール | Viewのカタチ | うれしいところ | |
---|---|---|---|
Native | する | プラットフォーム | OSが提供するAPIにそのままアクセスできる |
SPA | しない | Web/独自 | Webアプリケーションとして管理すれば良い |
PWA | しない | Web/独自 | SPAにPush通知などのNativeアプリ要素を追加できる |
TWA | する | Web/独自 | PWAをストアから配布できる |
Cordova | する | Web/独自 | Webの技術を用いて、インストール可能なアプリを作れる |
Xamarin | する | プラットフォーム | C#を利用できる、ビジネスロジックをC#で共通化できる |
Unity | する | 独自 | Unityによる3D表現がしやすい |
ReactNative | する | Web/独自 | PWA + プラットフォームのViewを利用できるので描画が高速 |
Flutter | する | Material Design | Flutterが高速に描画する仕組みを持つため、ネイティブ並みに描画が高速 |
誰にとって嬉しいマルチプラットフォームか
アプリのパフォーマンス、つまり描画速度やバッテリー消費、タップ時の反応からアプリ立ち上がり速度まで考えれば、Nativeで開発するのが最も良い選択肢となります。*4 とりわけAndroid App Bundleやbitcodeなど、配布されるアプリのサイズを削減できる対応は、他の追従を許しません。
そんなわけで、マルチプラットフォームは開発する側にとって嬉しい理由があります。 大まかに、それぞれの技術について書き出してみると、下記のような印象です。
- Web技術に寄せたいケース
- SPA, PWA
- TWA, Cordova
- SPAやPWAをベースに、「端末にインストールできるようにしたい」という要望に答える
- 企画者、そしてWebアプリケーション開発者にとって嬉しい
- ブラウザのブックマークではなく、端末のホーム画面のポジションを確保できるようにする
- SPAやPWAをベースに、「端末にインストールできるようにしたい」という要望に答える
- ReactNative
- 「Webの技術を利用しつつ、Nativeと同等の描画速度を実現したい」という要望に答える
- 企画者、そしてWebアプリケーション開発者にとって嬉しい
- NativeのUIによるOS標準の採用、Webのスタイルの適用による独自デザイン、そのどちらにも道が開いている
- 「Webの技術を利用しつつ、Nativeと同等の描画速度を実現したい」という要望に答える
- ビジネスロジックをサーバーと共通で書きたいケース
- プラットフォームに関わりなく、独自のViewを表示したいケース
- 前提として、ここに分類されるプラットフォームは「OSごとのViewの違い」が存在しにくいものになります
- Unity
- 「3D表現を行いたい」という要望に答える
- 企画者にとって嬉しい
- (ビルド周りは大変だと聞くが、)Unityの開発の流儀に則ることで、既存のアプリケーション開発と異なる開発スタイルを採用できる
- 「3D表現を行いたい」という要望に答える
- Flutter
- 「OSやプラットフォームごとの差異を極力意識しない開発をしたい」という要望に答える
- 企画者、デザイナーにとって嬉しい
- (私見になるが、)一部のアプリケーションでは、Nativeで冗長なライフサイクルの概念を簡略化して扱うことができ、開発や検証の負荷を下げることができる
- Nativeアプリケーションエンジニアにとって(一部のケースでは)嬉しい
- 「OSやプラットフォームごとの差異を極力意識しない開発をしたい」という要望に答える
Nativeアプリケーション開発からマルチプラットフォーム開発に移行するメリット
前述の通り、Nativeアプリケーション開発を行える状態であれば、マルチプラットフォームによる開発に「移行しなければならないような」強いメリットはありません。 *5
Native SDKのAPIに強く依存するようなアプリであれば、マルチプラットフォームの採用は明らかな悪手になるとすら感じています。 これは、結論付けてしまうなら「マルチプラットフォームの採用は、開発工数や、開発にかかる負荷を下げる」ためのものであって、各プラットフォームにフィットするアプリを作るためのものではない、と言えるからです。*6
上の文章を踏まえた上で、自分が考えるマルチプラットフォームを選択する理由、アプリケーションのガワで採用する理由は次の3つです。
- (後発プラットフォームであるが故に、)アプリケーション開発を助けるツールがよくできているため、高速な開発がしやすい
- (Nativeアプリエンジニアが希少であるが故に、)少ないエンジニアで複数プラットフォームにアプリを提供できる、場合によっては(Webの技術であれば)採用できるエンジニアの数が多い
- プラットフォームの流儀に則らないアプリケーションの開発を行う、という選択肢を採用できることがある
アプリケーション開発を助けるツール
ガワの開発である以上、高速に開発してチェックするフローを回すことが(近年では特に)求められています。 その状況下で生まれたプラットフォームであるため、マルチプラットフォームの開発を助けるツールは、とっつきやすく便利な印象です。 ReactNativeやFlutterのエンジニアが「Hot Reloadがない開発に戻れない」なんていうのは、この辺りのことを指していると理解しています。
とはいえ、実の所Nativeアプリの開発で用いるIDEには、ほぼ同等か場合によってはそれ以上に高機能なツールが搭載されています。 問題は、それらのツールが「開発中に利用する」ことが前提であったり「利用のために必要となる知識」が多かったりすることです。良くも悪くも、プロ向けツール。 *7
採用できるエンジニアの数
近年、「特にAndroidエンジニアが採用できない」という声が聞こえるようになりました。 聞くところによると、外部の採用から内部で育成する方針に切り替えたところもあるとか。
Nativeアプリケーション開発は、個人的には非常に好みの開発ではありますが、Webアプリの開発に比べるととっつきにくい印象が持たれがちです。 いわゆるエンジニア育成コースでも、大抵はバックエンドかWebフロントエンドのコースっぽいので、間口も狭い印象があります。 自分も1社目で関わることがなければ、たぶんAndroidアプリ書くようになってないですしね。
このような状況なので、マルチプラットフォームの採用によってエンジニアの確保の難易度が変わる(ことがある)ようです。 北米だとそんな感じだ、というのをこの間ポッドキャストで耳にしました。
とはいえ、「すべてのマルチプラットフォーム」で採用できる間口が広くなる、なんてことはありません。 その辺りは、技術採用する人の情報感度によるんでしょうね……。 *8
プラットフォームの流儀に則らないアプリケーションの開発
Pokemon GOのアプリを開いて、「iOSアプリっぽい」や「Androidアプリっぽい」と誰も言わないと思います。
特に独自の描画を行うプラットフォームでは、そのプラットフォームの流儀から外れた開発をすることができます。 もちろん、流儀に従わないというのは場所を選ぶ必要がある行為である、ということを踏まえた上での話です。
過去に「Android SDKを使って、iOSっぽくする」という各所で見られた仕草が、今ではほとんど残っていません。 逆のパターンは、iOSでカスタマイズしすぎると大変なことになるので、そもそもチャレンジしている箇所が少ないんじゃないかなと思っています。 Native SDKを使って、もう一方のシステムに合わせるのは、そもそも無理のある話かなと。
個人的に「プラットフォームの流儀に則らないアプリケーションの開発」に成功していると思っているのが、DiscordのiOSアプリです。
apps.apple.comDiscordはReact Nativeを早くから採用しているアプリであり、そのUIは素晴らしいと感じています。 何がすごいってiOSの流儀に載ってないんですけど、納得させられる体験があることです。
NativeのViewの描画の上に載っていても、独自性を出せるという意味で、適切なマルチプラットフォームの採用はアリだと思っています。
とここまで「インストールする」アプリを書いていたのですが、この分野で言えば「インストールしない」アプリの方が事例が多くなります。 色々なデザインシステムの採用であったり独自のレイアウトであったり、自由があります。 うーん、話がこじれてきた。
「インストールする」アプリにおいて対抗馬になるのはFlutterだと、個人的に思っています。 理由は単純で、FlutterはSkiaで描画されるプラットフォームだからです。
現時点では、コミュニティ側で「SDKが提供するWidgetによらない」開発が進んでいない(モチベーションあるのかすら怪しいですが)ので、基本的にはMaterial Designに則った開発をしていくことになります。 私見ですが、たぶんこの状況をどうにかできるのかな? と上げられている観測気球がFlutter Createです。
Flutter Create is a contest that challenges you to build something interesting, inspiring, and beautiful with Flutter using 5KB or less of Dart code.
とは言えMaterial Youがそれに歯止めをかけようともしているので、プラットフォームの発展と開発者コミュニティの囲い込みは、これから激化しそうです。 マルチプラットフォームの明日はどっちだ。
おわりに
なんとなくマルチプラットフォームについて、比較したり感想を述べている人が少ないなーと思って書き始めたブログでした。 何書けばいいのかわからなくなり、1月ぐらいこねくり回していたのはここだけの秘密。
Androidアプリをメインで書いていると、時たま「世の中では、開発の話するときってAndroidはおまけだよなー」と感じます。 iPhoneは色々と完成してますし、基本的に高級機ですし、日本だとユーザー数が多いのでそれはそうって話です。
他方で、Androidが「多様なデバイスにおいて、60fpsを提供する」ために色々と取り組んでいたことは、本来はしていいものではないと思っています。
よくいう話ですが、開発者のマシンって基本的にハイスペックで、高速なインターネットにつながっている環境ですよね。
ギガ
だって基本的に気にしていないし、端末には十分な空き容量がある。言うなれば、実験室的な環境です。
マルチプラットフォーム開発において、その辺りの実環境に対して配慮しているかどうかは、あまり俎上にのぼりません。 個人的には、この辺りについてもっともっと議論しないと、ユーザーからそっぽ向かれる日も来るんじゃないかなと思っています。 当たり前品質のエリアなんですよね、たぶん。
アプリだけに限った話をすると。Webから、表示速度を求めて魔改造を挑んだ結果がReactNative。Mobileから、描画を統一的なエンジンの上に求めたのがFlutterという印象。
— Koji Wakamiya(だぐりば) (@D_R_1009) September 7, 2021
ややこしいのが、クロスプラットフォームで一番成熟しているモノがWebブラウザってところなんじゃないだろうかと最近思っている。
*2:詳しくはAndroidを支える技術〈II〉を参照してください。
*3:といっても、そもそもAndroid/iOSのネイティブSDKと比較でもしなければまとめる必要はないのですが。
*4:それぞれのプラットフォームで、部分的に勝つ箇所はあれど、総合的にみれば議論の余地はないというのが自分の立場です。
*5:GoogleがイGoogle Payアプリを書き換えた例をよく挙げていますが、Javaで書かれていたコードを置き換えるケースは、ちょっと過大な評価になると思っています。
*6:一部例外として、Unityがあるとは思っています。アレはすごい。
*7:プラットフォームについて語るのが作業者になりがちなので、ここは意見が強くなりがち。
*8:特にコメントはありません。