
先日、NativeScript-vueで、WebViewとアプリ間でデータのやり取りってどうするんだろう?と疑問に思って実際に調査してみました。
今運営しているAnybookをアプリ化する時に、HTMLを利用したアイテム達をどうしても利用したいと考えていて、Webとアプリの間でデータ通信できたら便利だなぁという考えに至りました。(他にもいろいろ理由がありますが…)
2019年現在、NativeScript-vueの記事はとにかく少ない状況なので、上記のようなデータ通信をやりたい人の助けになればと思います。
目次
WebViewタグでは難しい!?
NativeScriptにはWebページを表示させることができるWebViewタグというものが標準であります。
ですがこのWebViewタグだけでは、データ通信は少し難しいです。
localstorageやSQLiteなどをまず考えましたが、以下の理由から実現不可能でした。
・localstorage
localstorageはそもそもブラウザにデータを保存させる為の技術で、ブラウザで表示しているわけではないのでデータはアプリ側では扱えません。
・SQLiteなどの内部データベース
次にデータベースを考えました。
アプリ側からはNativeScript-Sqliteのようなプラグインを利用すればSQLiteへの読み書きができるようですが、
WebView側(Webページ)はJavaScriptで読むことは出来ても、書きこむことが出来ません。
(厳密には出来るの方法があるのかもしれませんが…)
同じ理由でJSONファイルにデータ登録してのやり取りもボツで、Web側では書き込みが出来ません。
WebView拡張プラグインに頼ろう!
どうしても己の力では解決しそうになかったので、機能拡張プラグインを探すことに。
最初に「Nativescript-WebView-Interface」というWebView拡張で人気のあるらしいプラグインを見つけました。
しかし、Vue版はサポート対象外で、海外記事をあさりましたが「Vue版での使い方がわからない」という文献だけが沢山見つかるだけでした…涙
NativeScript WebView Interfaceを一度諦めて別のプラグインがないか調査していると、Vueもサポートしている「nativescript-webview-ext」というプラグインを発見しました。
結論から言いますと、このプラグインでWebView×アプリの疎通を取る事が概ね可能でした!
(概ねな理由は後述します)
nativescript-webview-extの使い方
インストール&準備
GitHubのREADMEの通り、下のコードでインストールします。
1 |
tns plugin add @nota/nativescript-webview-ext |
拡張されたUIを利用できるようにするため、main.jsに以下のコードを追加する。
1 |
Vue.registerElement('WebViewExt', () => require('@nota/nativescript-webview-ext').WebViewExt) |
App.vue(アプリページ)の設定
main.jsに設定した「WebViewExt」というタグを利用出来るようになります。
このタグは、GitHubのREADMEにあるような様々な関数やイベントを扱う事が出来ます。
1 |
<WebViewExt ref="webviewext_test" id="webviewext_test" @eventTest="eventtest" /> |
「@eventTest」というイベントを入れていますが、このように自作したイベントを設定することでWebViewからのイベントを取得することが出来ます。
WebViewのイベントをアプリ側でキャッチする方法
前提としてApp.vueにこのようなWebViewExtタグを用意したとします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
<template> <WebViewExt ref="webviewext_test" id="webviewext_test" @eventTest="eventtest" /> </template> <script > import { isAndroid, LoadEventData, LoadFinishedEventData, ShouldOverrideUrlLoadEventData, WebAlertEventData, WebViewExt } from "@nota/nativescript-webview-ext"; let page; let webview; export default { data() { return { msg: "アプリ側", eventmsg: "テスト" }; }, mounted() { page = this.$refs.webviewext_test.nativeView; webview = page.getViewById("webviewext_test"); webview.loadUrl("~/assets/htmls/hoge.html"); }, methods: { eventtest(args) { this.eventmsg = "WebViewからのイベント確認"; console.log(args.object); } } }; </script> |
「@eventTest」はイベント名で、WebView側のjavaScriptで使用します。
「”eventtest”」はApp.vueに作った関数名です。このイベントをキャッチした時に関数を起動させます。
【App.vue(アプリ側)】
1 2 3 4 5 |
methods: { eventtest(args) { console.log("WebViewからのイベント確認"); } } |
【hoge.html(Web側)】
1 2 3 4 5 6 |
<script> function hoge_event() { // window.nsWebViewBridge.emitの引数にApp.vueで指定した発生させたいイベント名を設定する window.nsWebViewBridge.emit("eventTest"); } </script> |
これでWebView内のhoge.htmlの「hoge_event」関数が呼び出されると、App.vueの「eventtest」関数が呼び出されるようになります。
下のように情報のやり取りが可能になります。
ちなみに、戻り値を設定出来るようですが、どうやってアプリ側で戻り値を取り出せばよいかわかっていません…。
これが上記した「概ね」の原因で、知っている方がいれば教えてほしいです!
アプリのイベントをWebView側でキャッチ
WebViewタグに対してJavaScriptコードを発行することが出来ます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
// WebViewExtの要素を取得する let page; let webview; page = this.$refs.webviewext_test.nativeView; webview = page.getViewById("webviewext_test"); webview.loadUrl("~/assets/htmls/hoge.html"); // 取得した要素に対しJavaScriptを発行する webview.executeJavaScript("alert('HELLO!')"); // WebViewページ内にある関数を呼び出すこともできる webview.executeJavaScript("hoge()"); // WebView側のvue.jsのdataに値を代入することも可能 webview.executeJavaScript("app.test = 'あいうえお'"); |
下のように情報の受け渡しが可能になります。
まとめ
どうにかNativeScript-VueでもWebView・アプリ間でデータのやり取りを行う事が出来そうでした。
しかし、NativeScript-Vueはまだリリース間もないこともあり参考記事が本当に少ないです。
ですが、Vueでネイティブのようなクロスプラットフォームアプリ開発が出来るのはかなり魅力的なので、日本でNativeScriptが盛り上がってほしいなと思います。
データを取得する方法がわかりました。
下記argsから取得できます。
methods: {
eventtest(args) {
console.log(“WebViewからのイベント確認”);
}
}
args.objectはWebViewExtのオブジェクトです。
args.dataはwebViewから送られてくるデータです。