10
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

IonicAdvent Calendar 2018

Day 24

Cordova プラグインのコールバック地獄から脱却!Non-Angular アプリケーションでも Ionic Native を利用するという選択

Last updated at Posted at 2018-12-27

はじめに

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]);

The JavaScript Interface より引用

詳しくはこちらの記事を参照してください。

この、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 - Ionic Native より引用

つまり、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
.babelrc
{
  "presets": [
    [
      "env", {
        "modules": false
      }
    ]
  ]
}
webpack.config.js
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 を修正する必要があります。

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 で読み込むように修正します。

www/js/index.html
-         <script type="text/javascript" src="js/index.js"></script>
+         <script type="text/javascript" src="js/index.bundle.js"></script>

Ionic Natvie の Geolocation プラグインを呼び出し、Promise で記述します。

www/js/index.js
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 からインスピレーションを得たクロスプラットフォームを開発しているらしいですね。
こちらにも今後注目して行きたいです。

10
3
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?