Ionic/vue/capacitorアプリ制作における環境の整備

#はじめに
　ionic/vue/capacitorをすべて用いてプロジェクトを書こうという人はかなり少ないように感じられる。マルチプラットフォーム開発を目指してせっかくvue.jsとjavascriptを学んだのに、どのツールをどうやって導入すればいいかわからないから、初心者はなかなかJSコードを書くまでに至らない。こうした状況では環境整備のための初心者向け記事が望まれるところである。
　本来は数ある手法を網羅的に調査し、「どれをどう使えばどうプロジェクトの初期条件を揃えることができるのか」について概観的に説明することが必要であるのだが、今回はinoic/vue/capacitorによる手法を一つだけ紹介する。
　（いつか概説記事も書きたい）

## 用語の紹介
### Vue.js
　JavaScriptフレームワーク。
　JavaScriptは非同期処理のために、大規模開発が難しいという特性がある。そのために生まれたフレームワークの一つ。類似の用途を持つものにAngular, Reactがある。
　中でもVue.jsは最も後発のもので、学習コストの低さと小～中規模での開発のしやすさに特性があると言われる。
### Ionic
　マルチプラットフォーム開発のためのプロジェクトとツール群。かつて、PhoneGapやCordovaといったフレームワークが担ってきたマルチプラットフォーム開発を新しく刷新する取り組み。Webエンジニアにもありがたい美麗なHTMLコンポーネント・アイコン集や、アプリ開発のためのCapacitorなどの下位プロジェクトと連続している。
### Capacitor
　ウェブ系の資産をアプリ開発にも活用するIonicのやり方に対して、そうしたプロジェクトにカメラやSMSといったスマホネイティブな機能のAPIを提供するためのIonic下位プロジェクト。Cordova / PhoneGapといった旧世代（←おい）プロジェクトの資産もデフォルトで使えるようになっている（一部例外有り）。

# 想定している開発目的
 マルチプラットフォーム開発。または、web系の資産を流用しつつ、なおかつカメラやSMS機能などのネイティブ機能を活用しながらアプリ開発を行いたい。

　今回は、「Androidでもウェブでも動くカメラアプリ」を題材に、実装を進めていく。　以下、Vueのcliインストール、Android Studioのセットアップなどは済んでいると仮定する。

# 目標
1. vueプロジェクト動作確認
2. ionicインストール
3. capacitorインストール
4. ネイティブ機能プラグイン動作確認

# 著者の環境
- Windows 10
- Node.js v10.16.0
- @vue/cli 4.2.2

# 1. vueプロジェクト動作確認
## 1.1 プロジェクト新規作成
　Vue.jsとionic双方を用いる場合、プロジェクト作成においては、以下の２つの手段がある

 - `ionic init`
 - `vue create`

前者の手法では、ionicの設定jsonファイルが用意されるだけで、初心者のプロジェクト開始方法としては非常に物足りない物がある。そのため、今回はvue createを用いる。
コマンド例。ただしWindowsなので注意。
ここで後々使うことになる各種のモジュールもインストールしている。

1. `vue create {プロジェクト名}`  // defaultでよい
2. `cd {プロジェクト名}`
2. `vue add ionic`
3. `npm i @ionic/core @ionic/vue@0.0.9 vue-router @capacitor/core @capacitor/cli ionicons@4.5.9-1`

## 1.2 動作確認
次に、vue環境のテストを行う
`npm run serve`で、localhostにテストサーバーが立つだろう。まずはそこでテストページが見れるかどうかをチェックしてみよう。

うまく表示されない場合は？

1. ブラウザの開発者向けツール（の「コンソール」タブ）を見てみよう。
2. `npm run serve`を実行したコンソールにエラーが表示されていないか？

もしエラーを見つけたら、そのエラーコードを知ってそうな人かGoogleかあたりに聞いてみるといい。

#2 ionicインストール
##2.1 ionicの組み込み

main.jsに以下を追記。

```src/main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
+import Ionic from '@ionic/vue';
+
+Vue.use(Ionic);
Vue.config.productionTip = false

new Vue({
  router,
  render: h => h(App)
}).$mount('#app')
```
（出典： @ganessa 「Capacitor を 試してみる(router & ionicあり)」, <https://qiita.com/ganessa/items/d8452fd92335ea5c544a>, 閲覧2020/02/19）

##2.2 動作確認
　そうしたら、[このページ](https://ionicframework.com/docs/components)から好きなIonicコンポーネントを選んで組み込んでみよう。動作確認のためなのでなんでもよい。
　その際に、以下を変更しておくことを忘れない。

```src/App.vue
<template>
  <div id="app">

    ...

  </div>
</template>
```
このdivタグを、ion-appタグに変更する。

```src/App.vue
<template>
  <ion-app>  // ←

    ...

  </ion-app>  // ←
</template>
```

では、チェックしてみよう。
コマンドは`npm run serve`

# 3. capacitorのインストール
## 3.1 capacitor初期設定
コマンド例

1. `npx cap init` // 各種設定
2. `npm run build` // Vueプロジェクトのコンパイル
3. `rename dist www` // distフォルダをwwwにリネームする。
4. `npx cap add android` // 適宜 iosもインストールのこと。

## 3.2 動作確認
アプリのエミュレーターを使って、アプリの挙動を検証する。
コマンド例

1. `npx cap open android`
2. Android Studioが表示されていれば、おそらく画面上の緑矢印が点灯しているはずだ。それをクリックする。
3. プロジェクトがコンパイルされ、エミュレーターが起動し、アプリが起動するはずだ。

Android Studioをインストールしたり、エミュレーターで検証したりする手順については他を当たって欲しい。一般的なアプリ開発の下準備として紹介されている記事がたくさん見つかるはずだ。

エラーが起こった？以下を試してみよう。

1. Android Studioを再起動する
2. プロジェクトのandroidフォルダを消去して再び`npx cap add android`
3. エラーコメントを検索してみる

存外にもAndroid Studioの再起動で解決するケースは多い。

# 4. プラグインの動作確認
　カメラ機能プラグインは、Cordovaなどでも多くのツールが提供されているが、今回はcapacitor/coreが提供しているスマホ向けのカメラAPIを使おう。
　Web向けには、PWA-elementsというCapacitorの機能が優秀だ。
## 4.1 カメラプラグインの組み込み
　この、[capacitorが提供しているカメラ機能](https://capacitor.ionicframework.jp/docs/guides/ionic-framework-app#adding-camera-functionality)を実装する。
　ついでに、[PWA Elements](https://capacitor.ionicframework.com/docs/pwa-elements/)も実装してしまおう。手順をすべてすっ飛ばして、著者がうまく行ったソースコードを公開する。

```src/App.vue
<template>
  <ion-app>
    <ion-content>
      <img :src="photo.webPath" />
      {{this.photo}}
      <ion-fab vertical="bottom" horizontal="center" slot="fixed">
        <ion-fab-button @click="takePicture()">
          <ion-icon name="camera"></ion-icon>
        </ion-fab-button>
      </ion-fab>
    </ion-content>
  </ion-app>
</template>

<script>
import { Plugins, CameraResultType } from "@capacitor/core";   // カメラ機能のロード
const { Camera } = Plugins;   // カメラ機能のロード
import { defineCustomElements } from '@ionic/pwa-elements/loader';   // PWA-elementsのロード

export default {
  name: "App",
  data() {
    return {
      photo: ""
    };
  },
  mounted(){
    defineCustomElements(window);  // PWA-elements呼び出し
  },
  components: {},
  methods: {
    async takePicture() {  // カメラ機能の呼び出し
      const image = await Camera.getPhoto({
        quality: 90,
        allowEditing: false,
        resultType: CameraResultType.Uri,
        saveToGallery: false
      });
      this.photo = image;
    }
  }
};
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

```

## 4.2 動作確認
1. `npm i @ionic/pwa-elements` // pwa-elementsのモジュールインストール
1. `npm run build`
2. `rd /s www` // 古いフォルダの消去
3. `rename dist www` // distに生成されたデータをcapacitor所定のフォルダに移動
4. `npx cap sync`  // データ同期
5. `npx cap open android`  // 以降はAndroid Studioで

　ただし、ネイティブのカメラ機能は実機でないと実験できない。しかし、実は上記ですでにマルチプラットフォームに稼働するアプリが完成している。上記のコンパイル手法でなくても、`npm run serve`でリアルタイムにデバッグができる。

　カメラボタンを押してカメラを起動し、撮影したあと、画面に画像が表示されれば成功だ。
　以上。お疲れさまでした。

# Future works 著者の宿題
　veutify/cordova/vueの組み合わせでもマルチプラットフォーム開発ができるらしい。Vueに限っても、検討するべき手段は非常に多くある。総括的な結論を得るにはまだ至っていない。

# おわりに - この組み合わせの手触り
　Capacitor/Ionic/Vue.jsの組み合わせは、秀麗なアプリケーション開発をマルチプラットフォームに効率よく展開する事ができる。この利点は、自分のような時間のない学生には非常にありがたい。なぜなら、これさえ学んでおけば将来の活動幅が大きく広がるからだ。それは将来自分がやりたいことが変わったり、就職事情が変化したとしても、この技術が常に自分の中で輝きを失うことはおそらくない。僕はWebデザイナーも、フロントエンドエンジニアも、スマートフォンアプリデベロッパにもなれるし、逆に、学んだことをアプリでもウェブサイトでも表現できるという技術を学んでいる。これは投資としては非常に手堅い。
　とはいえ、この組み合わせならではの苦痛ももちろんある。この組み合わせでの開発は非常に文献が少ないし、そもそも要素技術が多いために、モジュール間でエラーが起こることもままある。おまけに、ionic/vueの組み合わせは未だに公式サポートされていない（公式ドキュメントはまだまだほとんどがAngular/Reactばかりだ）。おかげで僕は多大な時間をエラー処理に潰されたこともあった。
　それは、裏を返せばここが時代の先端ということでもある。多忙ながら、自分はこの未開の平野でやりたいことを自由に試しつつ、将来に意義のある地位を確保したいと思っている。そして、この組み合わせならそれができるはずだ。今後も苦労のあるたびに、積極的に記事を残していきたい。

#参考記事
https://qiita.com/ganessa/items/d8452fd92335ea5c544a