
Capacitor+Reactでスマホアプリ開発 AndroidもiOSもOK!クロスプラットフォーム開発
ブログの更新が滞っております。実は、筆者テック大家さんは、最近スマホアプリの開発をしていてブログまで手が回らないのです。
言い訳はさておき、本日は、AndroidもiPhoneも同時にサポートできる開発方法について語っていきましょう。
AndroidとiOSという二大巨頭
スマホのアプリ開発というと、大きくわけて2つのプラットフォームがあります。皆さんよくご存じ、Android とiOS ですね。
開発元はそれぞれ、GoogleとApple です。以前はもっといろんな種類がありました。Windows phoneなどというMicrosoft がやってたプラットフォームもありましたが、廃れましたね。
なので2025年現在は、GoogleとAppleの二大巨塔を押さえておけばだいじょうぶ。
とはいえ、2つのプラットフォームは全く別物。アプリを開発するプログラミング言語も全く異なります。プログラムを各側からすると、Android とiOSの対応をするには基本的には別物のものを2つ開発しなければならないわけです。
たとえば、プログラミング言語をとってみても、AndroidはJava、またはKotlin。一方のiOSはObjective-CまはたSwift。といった感じでそれぞれ別物なわけです。
クロスプラットフォーム(マルチプラットフォーム)対応
そこで登場してきたのが、マルチプラットフォーム対応やクロスプラットフォーム対応という考え方です。
要は、一度にAndroidもiOSも両方対応するようなプログラムを作りましょう、そのためにはこういう仕組みならOKだよね…という設計思想ですね。
そのアプローチには実は色々あって、さまざまなツールやライブラリが登場してきています。
ここでいくつか、紹介しましょう。
Xamarin (VMアプローチ)
1つ目は、Xamarinです。こちらは、Microsoftのアプローチです。Microsoftが開発したC#や.NET RuntimeをつかってAndroidとiOSで動作するアプリの共通コード化を目指した形になります。

開発者はC#でプログラミングすることになります。C#はAndroidのJavaと同様、コンパイル言語です。コンパイル結果は.NET Runtimeが実行可能なマシン言語にコンパイルして実行されます。
また、アプリのUIは.NETで定義されたコンポーネントであっても最終的には、OSのネイティブのUIコンポーネントに変換されて表示されます。
React Native (スクリプト・アプローチ)
2つめは、React Nativeです。こちらは、Web系で培われたReact というフロントエンドのライブラリがあるのですが、その設計思想をクロスプラットフォームアプリ開発に持ってきた、というものです。

開発者はWeb系でおなじみJavaScript/TypeScriptでプログラミングすることになります。JavaScriptはスクリプト言語なので、JavaScriptの実行エンジン、というものの上でプログラムが実行されます。
UIについては、名前の由来となったReactはHTML/CSSでレンダリングされる一方、React Nativeの場合は、最終的なUIコンポーネントはネイティブのUIに変換されます。
Flutter(ネイティブ・アプローチ)
3つめは、Flutterです。こちらは、Googleのアプローチです。Google が開発したDart言語というプログラミング言語で開発することになります。

前述の2つのアプローチは、プログラムはそれぞれ、JavaのVM(仮想マシン)やJavaScriptエンジンの上で動作します。一方、Dart言語はコンパイル言語です。コンパイル結果はそれぞれのCPUで実行可能なマシン語に変換されて実行されます。たとえば、Androidの場合、CPUアーキテクチャは、ARMやIntel(x86)など複数対応していますが、Dartでは別々のバイナリを生成し一つのPackageに収めるといった対応が必要になります。
また、UIに関しても、前述の2つのアプローチとはことなり独自にUIコンポーネントをレンダリングします。そのため、OSが違っても全く同じUIをもつアプリを実現できるというわけです。
ここまでのアプローチを整理すると以下のような表になります。
アプローチ | プログラミング言語 | 実行 | UIコンポーネント |
---|---|---|---|
Xamarin | C# | .NET Runtime | ネイティブ |
ReactNative | JavaScript/ TypeScript | JavaScriptエンジン | ネイティブ |
Flutter | Dart | マシンコード(CPU) | 独自 |
ちなみに、上で述べた「〇〇アプローチ」という分類は筆者が独自に便宜的に考えたものなので、一般的ではありません。あしからず…
Capacitorとは(ブラウザ・アプローチ)
さて、筆者テック大家さんが現在取り組んでいるアプリ開発は、これまで述べてきた対応とはことなるクロスプラットフォーム開発のアプローチになります。Capacitorというフレームワーク(ツール)を扱います。
テック大家さんはこれまでWebアプリ開発に勤しんできております(趣味です…)。
Webアプリは見た目部分の開発(フロントエンドと言ったりしますが…)はまた様々なフレームワークが登場しており、日々進化している状態です。フロントエンドのフレームワークとして何を選ぶかはともかく、このWeb系のアプリをそのままスマホに載せてしまおう、というアプローチが考えられます。
「ブラウザ・アプローチ」とでも呼びましょうか。
上述の分類で言いますと、実行エンジンはブラウザ(WebView)です。当然プログラミング言語はJavaScript/TypeScriptになります。UIコンポーネントはHTML/CSSで独自につくるので、「独自」ですね。
プログラミング言語はJavaScript/TypeScriptなのですが、フロントエンドのフレームワークは筆者の場合は、Reactを使っています。
Capacitorの一番のメリットは、Webブラウザで動作するWebアプリ(SPAやPWAと言ったりする)をそのままスマホアプリにできてしまうという点です。すでに、Webアプリとして公開しているようなものが開発済みであれば、ほぼそのままスマホアプリにできるということです。

(ざっくり)WebViewを立ち上げるアプリがCapacitor
ここでは、Capacitorの仕組みに関して少し説明します。
簡単に行ってしまうと、WebViewを表示するアプリが、言うなればCapacitorです。WebViewを起動するアプリとWebアプリのバンドルをひとまとめにするのがCapacitorというフレームワークなのです。
WebViewは、Androidにしろ、iOSにしろ、どちらのOSにも搭載されているHTML/CSSレンダリングエンジンです。何かしらのスマホアプリでHTMLを「アプリ内に」表示したい場合があります。その際に使われるコンポーネントがWebViewなのです。
Capacitorの場合は、WebViewをアプリ起動した直後に全画面に配置し、表示するコンテンツはネットから取るのではなく、アプリ自身が抱えているWebアプリバンドルにしてしまうと言うイメージです。ですので、WebViewだからといって、ネットがないと使えないアプリになるわけではないです。ネットにつながらなくても使えるスマホアプリがちゃんと作れます。
ネイティブ機能の対応 Capacitor プラグイン
さて、いくら「Webアプリをそのまま持ってこれる」といっても課題があります。一番のキモは、スマホに搭載されているハードウェアにアクセスしたり、スマホ独自の機能にアクセスする方法です。
例えば、位置情報を取りたい場合にスマホのGPSセンサーにアクセスしなければなりません。また、アプリ内購入を実装する際は、AndroidやiOSそれぞれの対応が必要になります。
こういったケースにもCapacitorは対応できます。大抵の場合、プラグイン(または、単にAPIと呼んでいたりする)がそれを担います。そして、それらのAPIはJavaScript/TypeScriptで簡単に呼び出すことができます。
導入するのも簡単そのもの。Web系の開発者であれば普通に使う「神コマンド」"npm install …"というのが使えるのです。なんというありがたい開発体験なのでしょう!
たとえば、位置情報を取得することを考えてみましょう。
導入するには、@capacitor/geolocationというプラグインをnpmでインストールします。
npm install @capacitor/geolocation
npx cap sync
あとはTypeScriptで(Reactの場合)、以下のコード。
import { Geolocation } from '@capacitor/geolocation';
// ... 略 ...
useEffect(() => {
let watchId: string | null = null;
Geolocation.watchPosition({ maximumAge: 0, timeout: 5000 }, (position) => {
if (!position) return;
const pos = {
lat: position.coords.latitude,
lng: position.coords.longitude,
accuracy: position.coords.accuracy
};
onGeolocationUpdated(pos);
}).then((callbackId) => { watchId = callbackId })
return () => {
if (watchId) {
Geolocation.clearWatch({ id: watchId });
}
}
}, [onGeolocationUpdated]);
GeolocationオブジェクトのwatchPosition()で自分の位置の変更があったときの通知を受け取る、といった使い方になります。
クロスプラットフォーム開発環境分類(整理)
というわけで、最終的に整理してみましょう。先に提示した表に、React + Capacitorを入れるとこうなります。
アプローチ | プログラミング言語 | 実行 | UIコンポーネント |
---|---|---|---|
Xamarin | C# | .NET Runtime | ネイティブ |
ReactNative | JavaScript/ TypeScript | JavaScriptエンジン | ネイティブ |
Flutter | Dart | マシンコード(CPU) | 独自 |
React + Capacitor | JavaScript/ TypeScript | WebView | 独自 |
アーキテクチャーも整理してみます。以下の図は、AI(Claude)に頼んで書いてもらいました。

ディスカッション
コメント一覧
まだ、コメントがありません