Cordova

HTML が携帯アプリになるという [Cordova](https://cordova.apache.org/) を試してみた。簡単そうで意外と引っかかったのでメモ。Version 8.0.0 時点の記録です。

## HTML としてアプリを実行

Cordova は様々なプラットフォームをサポートしていますが、`browser` を使うと PC のブラウザを使って簡単に実行する事が出来ます。初期プロジェクトを作ってからブラウザで実行する手順です。

```
$ npm install -g cordova
$ cordova create cordova-test
$ cd cordova-test 
$ cordova platform add browser
$ cordova run browser
```

Cordova はかなりバージョン依存があるので、`npm install cordova` でプロジェクトごとにインストールして `npx cordova` で実行した方が良いかも知れません。

## Android アプリとして実行

Android アプリを作るには `android` プラットフォームを追加します。

    $ cordova platform add android

他にも Android SDK 等こまごまと[以下のような必要ツール](https://cordova.apache.org/docs/en/latest/guide/platforms/android/index.html#requirements-and-support)をインストールしておく必要があります。cordova のバージョンによって違ってくると思うので、`cordova requirements` コマンドで確認しながらインストールします。

* Java Development Kit http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
    * *(注意点)* Java 9 だとだめらしい。Java 8 を入れる。https://stackoverflow.com/a/46405092/616909
* Android Studio https://developer.android.com/studio/index.html
* *(注意点)* Android SDK 最新版ではだめ。android-26 をインストール。
    * Android Studio を開く > Configure > SDK Manager > android-26
* Gradle
    * `brew install gradle`

全部インストールしたら以下のような表示になりました。cordova にバグがあるのかまだちょっとエラーが出ますが気にしない。。。

```
$ cordova requirements
Android Studio project detected

Requirements check results for android:
Java JDK: installed 1.8.0
Android SDK: installed true
Android target: installed android-27,android-26
Gradle: installed /usr/local/Cellar/gradle/4.4.1/bin/gradle

Requirements check results for browser:
(node:6705) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): TypeError: Cannot read property 'forEach' of undefined
(node:6705) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
```

Android 機を USB 接続してビルドと実行します。

```
cordova build android
cordova run android
```

出来上がり。

一旦 `cordova platform add android` を行うと [config.xml の engine](https://cordova.apache.org/docs/en/latest/config_ref/index.html#engine) に記録されるので、ソースを受け取った人は `cordova platform add android` を使う必要はありません。`cordova prepare` の時に適切なバージョンがダウンロードされます。

## 分かりにくかった機能

### [cordova prepare](https://cordova.apache.org/docs/en/latest/reference/cordova-cli/#cordova-prepare-command)

`cordova prepare` はファイルをコピーするなどビルド前の準備を行います。その過程で config.xml の情報を元に必要な platform や plugin をダウンロードします。ということは `cordova prepare` と `build.xml` は `npm install` と `package.json` の関係と似ています。

[cordova run](https://cordova.apache.org/docs/en/latest/reference/cordova-cli/#cordova-run-command) コマンドには `cordova prepare` と `cordova build` の機能が含まれています。ということは `cordova run` だけを行えば依存プラグインのダウンロードとビルド、実行を一度に出来るような気がします。ただし、platform をインストールしていない状態から `cordova run` すると platform が無いエラーになってしまうので、初回に関しては `cordova platform add` `cordova requirements` `cordova prepare` などを一つ一つ実行した方が良いです。

さらにこの `cordova prepare` はなぜか pakcage.json の内容を元に build.xml を再構築するというような余計な事もします。多分整合性を取るためでしょうか? なので build.xml が勝手に更新される謎の挙動は `cordova preppare` のせいです。

## バージョンコントロール

[platform/ と plugins/ は git に入れない](https://cordova.apache.org/docs/en/latest/reference/cordova-cli/index.html#version-control) `cordova prepare` 実行時にダウンロードする。

## トラブルシューティング

* `No target specified and no devices found, deploying to emulator`
    * Android 実機がつながっていない時に起こる。`adb devices` で確認する。
* `Error: spawn EACCES`
    * `chmod +x '/Applications/Android Studio.app/Contents/gradle/gradle-4.1/bin/gradle'`
    * 過去のバージョンの android platform では、Android Studio の中の gradle を検索していたが [上手く動かないのでやめたらしい](https://github.com/apache/cordova-android/commit/9fdb12671519e97e78c36f4d68025246334f7c04)。
    * 古い android platform 7 以前 では `chmod +x` で回避出来る。参考: [cordova buildでError: spawn EACCESが発生した時の対処方法](https://qiita.com/bathtimefish/items/7304f11ba4bbb36fd02d)
    * プロジェクトにインストールされている platform は `cordova platform ls` で表示出来る。

## 参考

* [Cordova Command-line-interface (CLI) Reference](https://cordova.apache.org/docs/en/latest/reference/cordova-cli/)