📱

[Capacitor] JavaScript で iOS、Android アプリを開発できる、Capacitor についてご紹介

2023/12/01に公開

この記事は、Capacitor Advent Calendar 2023 の1日目の記事です。

はじめに

今年も気づけば師走ですね。みなさん、今年も残りわずかとなり、忙しい日々をお過ごしのことと思います。

私は、普段業務で Capacitor を使ってモバイルアプリケーションの開発に携わっているエンジニアです。今日は、Capacitor Advent Calendar 2023 の初日を飾る記事として、Capacitor の魅力についてお話ししたいと思います。この記事が、みなさんの Capacitor の世界への一歩となるよう、私の少しばかりの経験と知識を共有できればと思います。

よろしくお願いします。

対象読者

  • JavaScript を用いた開発に慣れているがモバイル開発は初めての方
  • クロスプラットフォーム開発に興味があるがどの技術を選ぶべきか迷っている方

Capacitor の簡単な紹介

Capacitor は、JavaScript を用いてクロスプラットフォーム開発を可能にするライブラリです。ネイティブの API に直接アクセスできる強みを持っています。

https://github.com/ionic-team/capacitor

Capacitor を用いることによって、Web アプリケーションをネイティブアプリの Web View 内で動かし、さらにその Web アプリケーションからネイティブ特有の機能 (カメラ、プッシュ通知、ローカル通知、アプリの情報取得、通知バッジ、アプリ内ブラウザ、カスタム URL Scheme、ディープリンクなど) を呼び出すことができます。

公式サイトによる紹介は以下のようになっています。iOS、Android の標準的な作り方をしているので、パフォーマンスの高いアプリケーションを作ることができます。

Capacitorはクロスプラットフォームのネイティブランタイムで、最新のWebツールを使用して、iOS、Androidなどでネイティブに動作するパフォーマンスの高いモバイルアプリケーションを簡単に構築することができます。

サンプルプログラム

例えば、Capacitor を用いてカメラを起動するには以下のように書きます。Camera.getPhoto のようなネイティブ API を利用する機能の API は公式ドキュメントや GitHub の README にまとめられているため、容易に利用することができます。

Camera.getPhoto({
  quality: 90,
  allowEditing: true,
  resultType: CameraResultType.Uri
});

この処理を呼び出し、撮影した写真、または選択した写真をアプリ上に表示する処理を書くことによって、シンプルなカメラ機能を実装することができます。

camera.page.html
<ion-button (click)="takePicture()">Take Photo</ion-button>
@if (imgUrl) {
  <ion-img [src]="imgUrl"></ion-img>
}
camera.page.ts
async takePicture(): Promise<void> {
  const image = await Camera.getPhoto({
    quality: 90,
    allowEditing: true,
    resultType: CameraResultType.Uri
  });

  this.imgUrl = image.webPath;
}

動作は以下のようになります。iOS シミュレータだとカメラが起動できないので、写真ライブラリから選択しています。

Capacitor と Ionic Framework は何が違う?

Capacitor やクロスプラットフォームと聞くと Ionic Framework を思い浮かべる方がいるかもしれません。

https://github.com/ionic-team/ionic-framework

Capacitor と Ionic Framework はともに Ionic チームによってメンテナンスされているライブラリ、フレームワークなのですが、役割が違います。

Ionic Framework は、モバイルアプリ向けのクロスプラットフォーム UI ツールキットです。モバイルアプリの UI を構築するために必要な、セーフエリアを考慮したスタイリング、ボトムナビゲーション、ヘッダー、フッターのようなコンポーネントや、ルーティングの機能などが用意されています。iOS と Android でコンポーネントのスタイルが変わるので、それぞれのプラットフォームに特化した UI を構築することができます。iOS のスタイルは Human Interface Guideline に、Android のスタイルは Material Design に従ってデザインされています。

モバイルアプリ向けの UI/UX を構築するには Ionic Framework を用い、実際に iOS、Android アプリとして動かしたり、ネイティブ特有の機能を呼び出したりするには Capacitor を用いる、という認識で問題ないかなと思います。

実際の開発体験

Capacitor & Ionic の開発体験は良いと感じています。具体的なメリットを挙げると、以下のようになります。

  • Capacitor プラグインが利用しやすく、ネイティブの処理を簡単に呼び出すことができること
  • アプリ審査を挟まずに、Web View で動かす Web アプリケーションだけをリリースできる機能があること (Live Update)
  • iOS、Android アプリの UI/UX 改修を Web エンジニアだけで完結できること
  • Web エンジニアが iOS、Android のアプリ開発を徐々にキャッチアップしていけること

一番大きなところは開発生産性の観点ですね。Live Update の部分と UI/UX 改修を Web エンジニアだけで完結できること、は非常に良いです。

一方で、デメリットもあります。

  • ネイティブの機能をちゃんと実装するには、結局 Web エンジニアでもネイティブの知識が必要になること
  • ネイティブのバージョン管理やトラブルシューティングをする際、iOS アプリ開発と Android アプリ開発の基礎知識がないとハマること
  • Ionic Components を使うだけでパフォーマンスが劣化するケースがあったこと (特別なケースかも)

正直デメリットは Web エンジニアが頑張れば解決するのですが、現実は厳しく、課題になっているところになります。

バージョン管理やトラブルシューティングの対応などは、ネイティブを少しだけわかる人が横断的に対応していくのが現実解かなと思います。

アプリ審査を挟まずにリリースできる?

Ionic チームは、Capacitor アプリの CI/CD プラットフォームである Appflow を提供しています。Appflow もまた、Capacitor を採用する上での大きなメリットを持っています。

大きなところは、アプリストアを経由せずに Web アプリをリリースできる Live Update 機能です。Live Update を利用すると、アプリ審査を待つことなく、HTML、CSS、JS の更新を直接リリースし、バグ修正や新機能追加を行うことができます

Web アプリケーションの運用に慣れたエンジニアにとっては、とてもありがたい機能でした。アプリ審査を経由すると、緊急のバグ修正や細かい UI 修正をするときでもリリースまでどうしても時間がかかってしまうからです。アプリ審査は Apple や Google の人が直接アプリを操作しガイドラインに従ったフィードバックをしてくれるので、短いときで翌日、2-3営業日かかるときもあります。

Live Update も、SDK を利用して簡単に導入することができます。

npm install @capacitor/live-updates
npx cap sync
capacitor.config.ts
import { CapacitorConfig } from '@capacitor/cli';

const config: CapacitorConfig = {
  appId: 'com.company.appname',
  appName: 'My Capacitor App',
  webDir: 'www',
  plugins: {
    LiveUpdates: {
      appId: '042a1261',
      channel: 'Production',
      autoUpdateMethod: 'background',
      maxVersions: 2
    }
  }
};

export default config;

上記の設定を入れると、Appflow のダッシュボード上から GitHub のコミット単位でリリースを行うことができるようになります。

詳細は Live Update のドキュメントを参照してください。

Capacitor が提供する機能

では、Capacitor のコア機能を提供するライブラリと、ネイティブ機能を提供する Capacitor プラグインについて紹介します。

Capacitor のコアライブラリは、以下の4つの npm パッケージで構成されています。

  • @capacitor/core
  • @capacitor/cli
  • @capacitor/android
  • @capacitor/ios

@capacitor/core は、Capacitor の JavaScript に向けたコア機能を提供するライブラリです。@capacitor/cli は、Capacitor の CLI ツールで、Capacitor プロジェクトの作成や Web アセットの iOS、Android の埋め込みなどを提供します。@capacitor/android@capacitor/ios は、それぞれ Android と iOS で動作する Capacitor のコアライブラリです。

コアライブラリ

Capacitor 自体が提供する機能は意外とシンプルで、以下のようにまとめることができます。

  • Web アプリケーションを Web View で表示する機能
  • Web View で表示した Web アプリケーションとイベントをやり取りする機能
  • Capacitor プラグインの管理機能

Capacitor のコアライブラリは、あくまでも Web アプリケーションを Web View で動かすための機能を提供しています。実際にネイティブ機能への API を提供するのは、Capacitor プラグインになります。

Capacitor プラグイン

Capacitor プラグインは、ネイティブ機能を JavaScript から呼び出すためのライブラリです。Capacitor プラグインの実態は JavaScript のオブジェクトであり、このオブジェクトのメソッドを呼び出すと iOS、Android それぞれの API が実行されます。

先ほどコードを紹介したカメラ機能、Live Update は、Capacitor プラグインを利用して実装しています。Capacitor プラグインには、大きく分けて Ionic チームが管理する公式のプラグイン、コミュニティが管理するコミュニティプラグイン、個人が管理する独自プラグインがあります。

標準的なネイティブ機能は公式のプラグインで提供されていることが多いですが、Firebase (アナリティクス機能, プッシュ通知など) や Stripe といった外部 SDK に依存した機能はコミュニティプラグインで提供されることが多いです。

以下は、公式プラグインの一覧です。多くの機能が提供されていることがわかりますね。


実際の現場では、ユーザーが求める UI/UX を担保するために利用可能な Capacitor プラグインを探して導入し、Ionic Framework と JavaScript フレームワーク (Angular、Svelte など) と組み合わせてアプリケーションを開発しています。初めはネイティブのことが何もわからない Web エンジニアでも、Capacitor プラグインの iOS、Android の実装を見ることからネイティブ機能のキャッチアップができるので、比較的開発も育成もしやすい技術かなと思っています。

もっと知りたい方へ

本記事では Capacitor をなぜ使うのか、どのような機能が提供されているのかをご紹介しました。Capacitor は、ネイティブの機能を JavaScript から呼び出すことができるため、モバイルアプリ開発において、Web エンジニアがネイティブの知識を意識することなく開発を行うことができます。

Capacitor に興味を持っていただけた方は、以下の資料を参考に、ぜひ Capacitor や Ionic Framework を触ってみてください。

https://capacitorjs.jp/docs

https://ionicframework.com/docs

また、すでに Capacitor を触っているよって方は、本記事をさらに深掘りした内容 (Capacitor のコンセプト) を以下の資料で確認することができます。

https://tinyletter.com/ionic-max/letters/how-capacitor-works

終わりに

最後までお読みいただきありがとうございました。

Capacitor Advent Calendar 2023、他の方の参加もお待ちしております。よろしくお願いします。

Discussion