はじめに
「iOSアプリとAndroidアプリ、それぞれSwiftとKotlinで書き分けるのは正直しんどい」——モバイルアプリ開発に携わったことがあるなら、一度はそう感じたことがあるのではないでしょうか。プラットフォームごとに言語もUIコンポーネントも異なり、同じ機能を2度、3度と実装し直す作業は決して小さくないコストです。
Ionicは、そんな悩みをWeb技術で解決するUIツールキットです。HTML・CSS・JavaScriptという使い慣れた技術スタックだけで、iOS・Android・Webの3プラットフォームに対応したアプリを1つのコードベースから作り出せます。この記事では、Ionicの特徴からインストール方法、実際のコード例までを紹介します。
Ionicとは
Ionicは、ネイティブ品質のiOSアプリ・Androidアプリ・Progressive Web App(PWA)を、Web技術だけで構築できるオープンソースのUIツールキットです。React・Angular・Vueのいずれのフレームワークとも組み合わせられるほか、フレームワークに依存しないWeb Componentsとしても利用できます。ネイティブ機能へのアクセスには、姉妹プロジェクトである「Capacitor」を組み合わせるのが定番の構成です。
主な特徴
- 豊富なUIコンポーネント - タブバーやモーダル、リストなど、モバイルUIに必要な部品が一通り揃っており、iOS・Androidそれぞれのデザインガイドラインに沿った見た目に自動で切り替わります
- フレームワークを選ばない - React・Angular・Vueいずれでも同じ感覚で使え、既存プロジェクトの技術スタックを崩さずに導入できます
- Capacitorとの連携 - カメラやGPS、プッシュ通知といったネイティブ機能を、公式・コミュニティ製のプラグイン経由で呼び出せます
- PWA対応が標準 - 同じコードでWebアプリとしても公開できるため、ストア審査を待たずに機能を届けられます
インストール
Reactプロジェクトを例に、Ionicの導入手順を見てみましょう。まずはIonic CLIをグローバルにインストールします。
npm install -g @ionic/cli
新規プロジェクトを作成する場合は、以下のコマンドでReactテンプレートを選択します。
ionic start my-app tabs --type=react
cd my-app
ionic serve
既存のReactプロジェクトに追加する場合は、パッケージを個別にインストールします。
npm install @ionic/react @ionic/react-router
ネイティブアプリとしてビルドする場合は、Capacitorも合わせて導入します。
npm install @capacitor/core @capacitor/ios @capacitor/android
npx cap init
基本的な使い方
Ionic Reactでは、通常のReactコンポーネントを書く感覚でUIを組み立てられます。以下は、ボタンをタップするとリストにアイテムが追加されるシンプルな画面の例です。
import React, { useState } from 'react';
import {
IonApp,
IonHeader,
IonToolbar,
IonTitle,
IonContent,
IonButton,
IonList,
IonItem,
IonLabel,
} from '@ionic/react';
const App: React.FC = () => {
const [items, setItems] = useState<string[]>([]);
const addItem = () => {
setItems((prev) => [...prev, `タスク ${prev.length + 1}`]);
};
return (
<IonApp>
<IonHeader>
<IonToolbar>
<IonTitle>タスク一覧</IonTitle>
</IonToolbar>
</IonHeader>
<IonContent className="ion-padding">
<IonButton expand="block" onClick={addItem}>
タスクを追加
</IonButton>
<IonList>
{items.map((item, index) => (
<IonItem key={index}>
<IonLabel>{item}</IonLabel>
</IonItem>
))}
</IonList>
</IonContent>
</IonApp>
);
};
export default App;
IonHeaderやIonContentといったコンポーネントを組み合わせるだけで、iOSでは丸みのあるボタン、Androidではマテリアルデザイン風のボタンというように、プラットフォームごとに適切な見た目が自動で適用されます。
実践的なユースケース
実際のアプリでよくあるのが、Capacitor経由でネイティブのカメラ機能を呼び出すケースです。以下は、カメラで撮影した写真を画面に表示する例です。
import React, { useState } from 'react';
import { IonButton, IonImg, IonContent } from '@ionic/react';
import { Camera, CameraResultType, CameraSource } from '@capacitor/camera';
const PhotoCapture: React.FC = () => {
const [photoUrl, setPhotoUrl] = useState<string | undefined>();
const takePhoto = async () => {
const photo = await Camera.getPhoto({
resultType: CameraResultType.Uri,
source: CameraSource.Camera,
quality: 80,
});
setPhotoUrl(photo.webPath);
};
return (
<IonContent className="ion-padding">
<IonButton expand="block" onClick={takePhoto}>
写真を撮影
</IonButton>
{photoUrl && <IonImg src={photoUrl} />}
</IonContent>
);
};
export default PhotoCapture;
@capacitor/cameraプラグインを使うことで、ネイティブのカメラAPIを直接叩くコードを書かずに、Web APIのような感覚で写真撮影機能を実装できます。同様の考え方で、位置情報やプッシュ通知、ファイルシステムへのアクセスなども公式プラグイン経由で扱えるため、「ネイティブ機能が必要だからネイティブ言語で書き直す」という判断を避けやすくなります。
まとめ
Ionicは、Web技術の知識をそのまま活かしながら、iOS・Android・PWAという3つの出力先を1つのコードベースでまかなえるUIツールキットです。React・Angular・Vueいずれの環境にも馴染みやすく、Capacitorと組み合わせることでネイティブ機能へのアクセスも無理なく実装できます。
「モバイルアプリも作りたいけれど、ネイティブ開発に踏み出すほどのリソースはない」という場面では、既存のフロントエンド資産を活かせるIonicが有力な選択肢になるはずです。まずはionic startコマンドでサンプルプロジェクトを作り、実機やシミュレータで動かしてみることをおすすめします。