はじめに
Ionic ユーザー向けというより Cordova ユーザー向けの記事です。
筆者は、諸事情により Cordova を利用してモバイルアプリケーションを開発しています。
WebView 内の SPA は Riot.js だったり React だったりです。
突然ですが、**Cordova って辛くないですか?**笑
何が辛いか挙げていくとキリがないので今回は省略しますが、
そんな辛さの一つを Ionic を利用して解決出来ますよというお話です。
Cordova プラグインのコールバック地獄
Cordova アプリケーションを開発している方々には理解して頂けると思います...。
基本的に Cordova プラグインは、引数に成功時・失敗時のコールバック関数を受け取るようになっています。
そのため、Cordova アプリケーションはコールバック地獄になりがちです。
これは、ネイティブプラットフォームと通信するための cordova.exec
が引数に成功時・失敗時のコールバック関数を受け取るようになっていることに起因しています。
cordova.exec(function(winParam) {},
function(error) {},
"service",
"action",
["firstArgument", "secondArgument", 42, false]);
詳しくはこちらの記事を参照してください。
この、Cordova プラグインによるコールバック地獄から脱却するにはどうすれば良いでしょうか?
Cordova プラグインを Promise でラップしてあげれば脱却できそうですね。
しかし、Cordova プラグインをインストールする度にラッパーなんて作るの面倒・・・。
そんな方々に Ionic Native の利用をお勧めします!
Ionic Native 利用できるのは Angular アプリケーションだけでしょ?と思った方々も安心して下さい。
React や Vue アプリケーション等の、 Non-Angular な Cordova アプリケーションからでも利用することが可能です。
Ionic Native を利用するという選択
Ionic Native の Overview には以下のような記載がされています。
Ionic Native is a TypeScript wrapper for Cordova/PhoneGap plugins that make adding any native functionality you need to your Ionic mobile app easy.
Ionic Native wraps plugin callbacks in a Promise or an Observable, providing a common interface for all plugins and ensuring that native events trigger change detection in Angular.
つまり、Ionic Native は Promise または Observable で Cordova/PhoneGap プラグインをラップした TypeScript ラッパーです。
そのため、以下のようなメリットを享受することが可能です。
- Promise または Observable によるコールバック地獄からの脱却
- TypeScript による型の恩恵
TypeScript で記述していればコールバック地獄からの脱却に加え、型の恩恵も享受することができます。
逆にデメリットとしては、 @angular/core
が必要となることでしょう。
これは、Ionic Native で @Injectable
デコレータが利用されているためです。
以下の機能要求が受諾されれば、Non-Angular アプリケーションでは @angular/core
は不要になるかもしれません。
Using in React project · Issue #2687 · ionic-team/ionic-native
Non-Angular アプリケーションからの Ionic Native の利用
それでは、Ionic Natvie の Geolocation プラグインを Non-Angular アプリケーションから利用してみます。
Cordova プロジェクトの作成
$ cordova create cordova-with-ionic-native
$ cd cordova-with-ionic-native/
プラットフォームの追加
$ cordova platform add ios
$ cordova platform add android
環境構築
webpack と Babel で環境を構築します。
$ npm install babel-core babel-loader babel-preset-env webpack webpack-cli --save-dev
{
"presets": [
[
"env", {
"modules": false
}
]
]
}
const path = require('path');
const webpack = require('webpack');
module.exports = {
entry: './www/js/index.js',
output: {
path: path.resolve(__dirname, 'www/js'),
filename: 'index.bundle.js',
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
},
],
},
devtool: 'source-map',
};
パッケージとプラグインのインストール
Ionic Native を利用するために必要なパッケージをインストールします。
$ npm install @angular/core @ionic-native/core rxjs --save
Geolocation プラグインをインストールします。
$ cordova plugin add cordova-plugin-geolocation --variable GEOLOCATION_USAGE_DESCRIPTION="To locate you"
$ npm install --save @ionic-native/geolocation
iOS の場合は config.xml
を修正する必要があります。
<platform name="ios">
<allow-intent href="itms:*" />
<allow-intent href="itms-apps:*" />
+ <edit-config file="*-Info.plist" mode="merge" target="NSLocationWhenInUseUsageDescription">
+ <string>need location access to find things nearby</string>
+ </edit-config>
</platform>
アプリケーションの修正
webpack によってバンドルされた JavaScript ファイルを HTML で読み込むように修正します。
- <script type="text/javascript" src="js/index.js"></script>
+ <script type="text/javascript" src="js/index.bundle.js"></script>
Ionic Natvie の Geolocation プラグインを呼び出し、Promise で記述します。
import { Geolocation } from '@ionic-native/geolocation';
document.addEventListener('deviceready', () => {
// onSuccess Callback
// This method accepts a Position object, which contains the
// current GPS coordinates
//
const onSuccess = position => {
alert([
`Latitude: ${position.coords.latitude}`,
`Longitude: ${position.coords.longitude}`,
`Altitude: ${position.coords.altitude}`,
`Accuracy: ${position.coords.accuracy}`,
`Altitude Accuracy: ${position.coords.altitudeAccuracy}`,
`Heading: ${position.coords.heading}`,
`Speed: ${position.coords.speed}`,
`Timestamp: ${position.timestamp}`,
].join('\n'));
};
// onError Callback receives a PositionError object
//
const onError = error => {
alert([
`code: ${error.code}`,
`message: ${error.message}`,
].join('\n'));
}
const geolocation = new Geolocation();
geolocation.getCurrentPosition()
.then(onSuccess)
.catch(onError);
}, false);
実行して確認して見て下さい。
問題なく動作します。
$ npm run webpack
$ cordova run ios
$ cordova run android
サンプルは GitHub 上で公開しています。
kotarella1110/cordova-with-ionic-native: Use Ionic Native in Apache Cordova
最後に
Ionic Native 然り、Ionic いいですよね...。Cordova の足りない部品や機能全てが整っている感じがします。
Ionic v4 から UI コンポーネントが Web Components ベースになり、 Non-Angular アプリケーションでも利用できるとのことで大変嬉しく思います。
Ionic CLI は Non-Angular アプリケーションでも利用できるようになったりしませんかね?
標準でライブリロードをサポートしていたり、Cordova CLI より API が充実していて魅力的です...。
Ionic team が Capacitor という Cordova からインスピレーションを得たクロスプラットフォームを開発しているらしいですね。
こちらにも今後注目して行きたいです。