Capacitorを用いたWebViewアプリの簡単レシピ

## はじめに

こんにちは！毎日寒いですね

今年5月に公表された[通信利用動向調査](https://www.soumu.go.jp/johotsusintokei/statistics/statistics05a.html)によると、個人がインターネット利用に使う機器の割合は次の通りだそうです。

- スマートフォン 63.3%
- パソコン 50.4%
- タブレット型端末 23.2%

今年に入って新規サービスの実証実験やテストマーケティングといった業務に携わっていますが、メインターゲットはモバイル端末だと肌で感じています。基幹系システムにおいても、タブレットやスマートフォンを活用して業務効率化を図りたい！というニーズが高まっているかと思います。

「実証実験をモバイルアプリでやりたい！」
「既存のWebサービスをアプリ化したい」

など、現場ニーズへの対応に迫られるシステム担当者も多いのではないでしょうか！？

とはいえ、ネイティブアプリの開発はそれなりにコストも期間もかかります。モバイル開発スキルを持ったエンジニアの調達も大変です。iPhoneとAndroidの両方をサポートともなると、予算獲得も困難を極めそうです。

そこで今回は、「Capacitorを用いたWebViewアプリの作成方法」を紹介したいと思います。
Capacitorを用いると、今あるWebサービスを簡単にネイティブアプリにすることが出来ます！
これを用いて、現場のニーズ ~~をお茶に濁~~ にお応えしましょう！

## Capacitorとは

Capacitorとは、クロスプラットフォーム開発フレームワークの１つです。WebViewでUIをレンダリングする方式を採っています。Cordovaと同じ技術方式というとピンとくる方も多いでしょうか。
Cordovaとの違いはネイティブコードに対する扱いにあります。Cordovaが開発者にネイティブコードを管理させない方針なのに対し、Capacitorはその管理を開発者に任せます。Cordovaよりネイティブよりでブラックボックス感が薄く、自由度が高いのがCapacitorの特徴と捉えています。

他のクロスプラットフォームフレームワークとの比較については、こちらの記事が分かりやすいかと思います。

[私にとってのCapacitorの立ち位置と、Web制作者がCapacitorでアプリをつくれるようになるということ](https://note.com/rdlabo/n/na41578be1871)

## お題

では早速WebViewを用いてお手軽にアプリを作ってみましょう。
今回のお題は次の通りです。

- 『TIS Advent Calendar 2020』をアプリにする
- Android端末に限定する

## Capacitorの導入と準備

ではCapacitorの導入から始めます。
事前条件として、npmとAndroid Studioはインストール済みとして話を進めます[^1]。
[^1]: Android Studioの開発環境構築手順については[ちょうどいい記事](https://qiita.com/mshuto/items/b42bc4fbea25f07ef4cf)が出たので、こちらを参考にしてください。

任意のディレクトリで次のコマンドを入力してください。

```
npx @capacitor/cli create
```
アプリ名、パッケージIDとアプリケーションのディレクトリを聞かれるので、それぞれ次のように入力してください。

`App name:` tis-advent-calendar-2k
`App Package ID:` com.gmail.kozake.sh.tis_advent_calendar_2k
`Directory for new app:` tis-advent-calendar-2k

パッケージIDはアプリケーション毎に一意である必要があります。適宜変更してください。

無事完了したら、作成したディレクトリに移動して動作確認してみます。次のコマンドを実行してください。

```
cd tis-advent-calendar-2k
npx cap serve
```

次の画面がブラウザに表示されればOKです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101517/be33a747-63c5-d88d-c852-41bb4faa813e.png)

## Androidアプリの作成

ではAndroidアプリを作成します。次のコマンドを実行してください。

```
npx cap add android
npx cap open android
```
Android Studioが起動します。実行するデバイスを選択して 「Run -> Run 'app'」で実行してください。
次の画面が表示されればOKです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101517/a0669402-b0a0-41e6-0f52-af2c69173ffe.png)

用意されているデモには、カメラとPhotoライブラリの機能がサンプルとして備わっています。Take Photoボタンを押してみてください。カメラが動くとネイティブアプリ感が出ますね！

## ライブリロード機能

JSコードをネイティブアプリのリソースとして組み込むのがCapacitorの普通の使い方です。しかし、`capacitor.config.json` 設定ファイルを変更することで、ライブリロード機能を実現できます。
今回この機能を用いて、アプリケーションのロード先を外部サイトに変更します。

`capacitor.config.json`を次のように変更してください。「+」マークが先頭についているところが変更箇所です。

```diff:capacitor.config.json
{
  "appId": "com.gmail.kozake.sh.tis_advent_calendar_2k",
  "appName": "tis-advent-calendar-2k",
  "bundledWebRuntime": true,
  "npmClient": "npm",
  "webDir": "www",
  "plugins": {
    "SplashScreen": {
      "launchShowDuration": 0
    }
+ },
+ "server": {
+   "url": "https://qiita.com/advent-calendar/2020/tis",
+   "cleartext": true,
+   "allowNavigation": ["qiita.com"]
  }
}
```

次のコマンドでこの変更をネイティブアプリに反映します。

```
npx cap sync
```

再度に、Android Studioで再実行してください。
次の画面が表示されればOKです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101517/c00c3363-f73c-096d-10e3-6f4ce4bd353e.png)

あとはこのアプリをGoogle Playに登録すれば完了です！

## 公開へ

Google Playに登録するにはプロダクションビルドやGoogle Playの審査が待ち構えています。
気合で乗り切りましょう[^2]。

[^2]: Androidアプリを公開する記事は多数公開されています。そちらを参考にしてくださいね。

僕も以前[ハンズオン](https://qiita.com/s_kozake/items/d590896e5303b75c0c6c)で作成した[Webアプリ](https://infallible-engelbart-709a39.netlify.app/#/event/search-root/search)を同じ方式でネイティブアプリ化し、Google Playで公開してみました[^3]。問題なくGoogle審査も通るのでご安心ください。

[^3]: 実際の動作を試してみたい方は[このURL](https://play.google.com/store/apps/details?id=com.gmail.kozake.sh.event_san)から試してくださいな。

以下、公開あたってのアドバイスです、

Capacitorではいくつかのパーミッションがデフォルトで有効になっています。カメラなど機密性の高い機能やデータへのアクセスをリクエストする場合、プライバシーポリシー公開サイトがGoogle審査で必要になります。必要ないパーミッションは削除しておくほうが面倒がなくていいでしょう。

```xml:AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
                :
                :
    <uses-permission android:name="android.permission.INTERNET" />
    <!-- Camera, Photos, input file -->
<!--    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>-->
<!--    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />-->
    <!-- Geolocation API -->
<!--    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />-->
<!--    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />-->
<!--    <uses-feature android:name="android.hardware.location.gps" />-->
    <!-- Network API -->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <!-- Navigator.getUserMedia -->
    <!-- Video -->
<!--    <uses-permission android:name="android.permission.CAMERA" />-->
    <!-- Audio -->
<!--    <uses-permission android:name="android.permission.RECORD_AUDIO" />-->
    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
</manifest>
```

## 最後に

以上、Capacitorを用いたWebViewアプリの簡単レシピでした。

現実としては、WebサイトをWebViewアプリとして公開するだけでは、現場ニーズを満たせないことがほとんどかと思います。とはいえ、いきなりネイティブアプリの作成に取り組むと提供までに時間がかかりますし、ニーズと異なるものを（時間とコストをかけて）提供してしまうリスクもあります。
Capacitorにはネイティブ機能と連携する様々なプラグインも（もちろん）用意されています。
まずは小さなところから始め、徐々に必要な機能を継ぎ足していくことで現場ニーズに対応していくのは如何でしょうか。