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
# プロジェクトをクローンする
$ git clone git@github.com:tetsushi-ito/ionic4-capacitor-sample.git
# ディレクトリを移動する
$ cd ionic4-capacitor-sample
# 必要パッケージをインストールする
$ npm install
# 一度ビルドする
$ ionic build
プロジェクトに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環境で呼び出そうとしたときにどうなるかを確認してみた。DatePickerプラグインの場合は以下のようにエラーが発生した。
# Ionicアプリをビルド
$ ionic build
# iOSのディレクトリにコピー
$ npx cap copy ios
# Xcodeを開く
$ npx cap open ios
Xcodeが起動したら、エミュレーターのiPhoneXSを選択して実行ボタンを押す。 ビルドターゲットのバージョン指定や、Swiftのコードの調整をしなければならなかったがなんとか動かせた。
# Ionicアプリをビルド
$ ionic build
# Androidのディレクトリにコピー
$ npx cap copy android
# Android Studioを開く
$ npx cap open android
Androidが起動したら、エミュレーターのPixel 2を選択して実行ボタンを押す。
アプリは起動したものの、AndroidではDatePickerを呼び出そうとするとJavaScriptエラーが発生してしまった。
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のプラグインを利用する方法を試してみたい。