Capacitorのプラグインを使ってネイティブのAPIを呼び出してみる

2019.02.21

はじめに

前回、Capacitorを使ってIonic製のWebアプリをiOS・Androidで動かせるようにしてみた。今回はさらに、Capacitorのプラグインを使ってネイティブの機能を呼び出してみようと思う。

Capacitorのプラグインは以下のページにリストアップされている。

https://capacitor.ionicframework.com/docs/community/plugins/

今回は検証のため、一番簡単そうで試しやすそうなDatePickerを試してみることにした。

ソースコード

https://github.com/tetsushi-ito/ionic4-capacitor-sample-datepicker-plugin

環境

  • macOS Mojave 10.14.2
  • Node.js v10.4.1
  • npm 6.8.0
  • Ionic CLI 4.10.3
  • Xcode 10.1
  • Android Studio 3.3.1

前回作ったIonic4でCapacitorを使うサンプルプロジェクトをクローンする



# プロジェクトをクローンする
$ git clone git@github.com:tetsushi-ito/ionic4-capacitor-sample.git

# ディレクトリを移動する
$ cd ionic4-capacitor-sample

# 必要パッケージをインストールする
$ npm install

# 一度ビルドする
$ ionic build

Capacitorプラグインを追加する

プロジェクトにDatePickerプラグインを追加する。



# DatePickerプラグインのパッケージをインストール
$ npm install --save capacitor-datepicker

# Capacitorに適用
$ npx cap sync

この時点でGitで変更を確認すると、以下のようなファイルが変更されていた。



$ git status
On branch master
Your branch is up to date with 'origin/master'.

Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

	modified:   android/app/capacitor.build.gradle
	modified:   android/capacitor.settings.gradle
	modified:   ios/App/Podfile
	modified:   ios/App/Podfile.lock
	modified:   package-lock.json
	modified:   package.json

アプリケーションにプラグインを利用した機能を呼び出す処理を追加する



<ion-header>
  <ion-toolbar>
    <ion-title>
      DatePickerプラグイン
    </ion-title>
  </ion-toolbar>
</ion-header>

<ion-content padding>
  <ion-button expand="block" (click)="showDatePicker()">DatePickerを表示</ion-button>
</ion-content>



import { Component } from '@angular/core';
import { DatePicker } from 'capacitor-datepicker';

@Component({
  selector: 'app-tab1',
  templateUrl: 'tab1.page.html',
  styleUrls: ['tab1.page.scss']
})
export class Tab1Page {

  date;

  async showDatePicker() {

    const picker = new DatePicker();

    const current = new Date();

    const response = await picker.show({
      mode: 'date',
      date: current.toISOString(),
      theme: 'AppDialogTheme',
      title: '日付を選択',
      okText: 'OK',
      cancelText: 'キャンセル',
      is24Hours: false,
    });

    this.date = response.value;
  }
}

一応Webでの動作を確認してみる

プラグインの機能をWeb環境で呼び出そうとしたときにどうなるかを確認してみた。DatePickerプラグインの場合は以下のようにエラーが発生した。

Capacitorのプラグインを使ってネイティブのAPIを呼び出してみる

iOSのエミュレーターに転送して動作を確認してみる



# Ionicアプリをビルド
$ ionic build

# iOSのディレクトリにコピー
$ npx cap copy ios

# Xcodeを開く
$ npx cap open ios

Xcodeが起動したら、エミュレーターのiPhoneXSを選択して実行ボタンを押す。 ビルドターゲットのバージョン指定や、Swiftのコードの調整をしなければならなかったがなんとか動かせた。

Capacitorのプラグインを使ってネイティブのAPIを呼び出してみる

Androidのエミュレーターに転送して動作を確認してみる



# Ionicアプリをビルド
$ ionic build

# Androidのディレクトリにコピー
$ npx cap copy android

# Android Studioを開く
$ npx cap open android

Androidが起動したら、エミュレーターのPixel 2を選択して実行ボタンを押す。

アプリは起動したものの、AndroidではDatePickerを呼び出そうとするとJavaScriptエラーが発生してしまった。

Capacitorのプラグインを使ってネイティブのAPIを呼び出してみる



ERROR Error: Uncaught (in promise): TypeError: Cannot read property 'show' of undefined
    TypeError: Cannot read property 'show' of undefined
        at DatePicker.show (http://localhost/tab1-tab1-module.js:41:33)
        at Tab1Page.<anonymous> (http://localhost/tab1-tab1-module.js:1488:53)
        at step (http://localhost/vendor.js:93321:23)
        at Object.next (http://localhost/vendor.js:93302:53)
        at http://localhost/vendor.js:93295:71
        at new ZoneAwarePromise (http://localhost/polyfills.js:3268:29)
        at Module.__awaiter (http://localhost/vendor.js:93291:12)
        at Tab1Page.push../src/app/tab1/tab1.page.ts.Tab1Page.showDatePicker (http://localhost/tab1-tab1-module.js:1481:63)
        at Object.eval [as handleEvent] (ng:///Tab1PageModule/Tab1Page.ngfactory.js:24:31)
        at handleEvent (http://localhost/vendor.js:56931:41)

DatePickerを初期化しているconst picker = new DatePicker();undefinedが返ってきてしまっている模様。 今回は検証に使うプラグインの選定が良くなかった可能性もあるので深追いしないでおく。

まとめ

Capacitorのプラグイン「DatePicker」を試してみた。このDatePickerプラグインはGitHubリポジトリのREADME.mdに書いてあるサンプルコードにも誤りがあり、さらにSwiftファイルも古い言語仕様で書かれている部分があった。Capacitorの進化に合わせて開発中かもしれない。

このようなプラグイン界隈の未成熟さがまだある可能性があるので、本番環境でCapacitorを使っていくならより綿密な検証が必要になりそう。

次はCapacitorでCordovaのプラグインを利用する方法を試してみたい。