2020年4月より、iOSアプリを新規申請する際にはWKWebView対応が必要となります。
(既存アプリの場合は、2020年12月以降の更新で対応が必要。)
Cordovaでアプリを作ると、デフォルトでUIWebViewを使用する(※執筆時)ため、
今後はこの対応が必要となってきます。
この記事では、自分がリリースしたアプリでWKWebView対応した際にハマったポイントを紹介していきます。
1.CordovaでのWKWebView対応
まずは今現在主流と思われる方法を、念のため記載します。
以下プラグインを使用します。
cordova-plugin-wkwebview-engine
インストール方法は上記リンク内に載っていますが、以下コマンドを実行します。
(Cordova iOSのバージョンは4.0以上である必要があるので、古い場合は最新等にします。)
1 | cordova plugin add cordova-plugin-wkwebview-engine |
プラグインを追加したら、config.xmlに以下を追記します。
1 2 3 4 5 6 7 8 | < platform name = "ios" > < preference name = "WKWebViewOnly" value = "true" /> < feature name = "CDVWKWebViewEngine" > < param name = "ios-package" value = "CDVWKWebViewEngine" /> </ feature > < preference name = "CordovaWebViewEngine" value = "CDVWKWebViewEngine" /> </ platform > |
これで対応自体は完了です。
問題はこの後で、UIWebViewとWKWebViewの仕様のズレによって、既存のアプリの動作に影響がでることがあります。
実際自分のアプリで上記を行った所、いくつか問題が発生したので、
発生した現象と対応方法をこの後紹介していきます。
2.SQLiteでエラー
見出しの通り、まず大きな問題としてSQLite関連のエラーが発生しました。
結果から見ると、そもそもの私の実装方法がマズかった可能性がありますが、一応紹介します。
症状
アプリ起動時のSQLiteデータベースへの接続でエラー。
当然、それ以降のDB関連の処理もすべてエラー
私のアプリは主にローカルDBにデータを保存していたので、これは非常に大きな問題でした。
調べてもピンポイントで何かがヒットするわけではなかったので、
地道にいろいろ試した結果、以下の2点を対処すると上手く動きました。
対処方法
① devicereadyイベントでDB接続を行う
② cordovaのSQLiteプラグイン(cordova-sqlite-storage)を使う
以下、それぞれの詳細を説明します。
対処① devicereadyイベント
対象のアプリにおけるデータベース接続処理は以下の様になっていました。
(実際のコードではなくイメージです。Vue.jsを使用しています。)
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 36 37 38 39 40 41 | <script> export default { name: 'App' , data: function () { return { db: null } }, created () { // デバイス判定 window.setTimeout(() => { if ( typeof cordova === 'undefined' ) { console.log( 'PC' ) this .onDeviceReady(); } else { console.log( 'スマートフォン' ) document.addEventListener( 'deviceready' , this .onDeviceReady, false ) } }, 1000) // DB初期化 this .db = window.openDatabase( 'test.db' , '1.0' , 'TEST DB' , 100000) this .db.transaction( this .initDB, this .errorCB, this .successCB) }, methods: { onDeviceReady () { console.log( 'device ready' ) }, initDB: function (tx) { tx.executeSql( 'CREATE TABLE IF NOT EXISTS sample (id integer PRIMARY KEY AUTOINCREMENT, name text)' ) }, errorCB: function (tx, err) { console.log( 'initDB Error : ' + err) }, successCB: function () { console.log( 'initDB success!' ) } } </script> |
かなり簡略化しましたが、構成的には上記のような感じです。
当初openDatabaseをどのタイミングで実行すべきかわからなかったので、
とりあえずcreatedで実装して問題が無かったのでそのままにしていました。(22行目)
さて、UIWebViewの時には上記の実装で問題が無かったのですが、WKWebView対応をしたタイミングでエラーを吐いたので、devicereadyイベント時にデータベース接続をするようにしました。
それが以下です。
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 | <script> export default { name: 'App' , data: function () { return { db: null } }, created () { console.log( '--- [START]App created ---' ) // デバイス判定 window.setTimeout(() => { if ( typeof cordova === 'undefined' ) { console.log( 'on PC' ) this .onDeviceReady(); } else { console.log( 'on スマートフォン' ) document.addEventListener( 'deviceready' , this .onDeviceReady, false ) } }, 1000) }, methods: { onDeviceReady () { console.log( 'device ready' ) // DB初期化 this .db = window.openDatabase( 'test.db' , '1.0' , 'TEST DB' , 100000) this .db.transaction( this .initDB, this .errorCB, this .successCB) } } } |
initDB等のメソッドは変わりないので割愛しています。
変わったのは、createdの中でDB初期化の処理をしていたのを、
onDeviceReadyメソッドの中で実行するように変更しました。
まず1点目はこちらになります。
対処② cordova-sqlite-storageを使う
もう一つ対応が必要だったのが、SQLite用のプラグインを使うことでした。
UIWebViewの時にも上記プラグインの存在は知っていたのですが、使わなくても動作したので使っていませんでした。
WKWebView対応でエラーを吐いたのをきっかけに、使って見たら上手く行ったという経緯です。
具体的な手順ですが、まずは以下でプラグインを追加します。
1 | cordova plugin add cordova-sqlite-storage |
そして、openDatabaseする際にこのプラグインを使うように変更します。
対象箇所はonDeviceReadyメソッド内で、以下の様に変更しました。
1 2 3 4 5 6 7 8 9 | onDeviceReady () { console.log( 'device ready' ) // DB初期化 this .db = window.sqlitePlugin ? window.sqlitePlugin.openDatabase({name: 'test.db' , location: 'default' }) : window.openDatabase( 'test.db' , '1.0' , 'TEST DB' , 100000) this .db.transaction( this .initDB, this .errorCB, this .successCB) } |
2点目としてこちらを変更することで、WKWebViewに変更後もDB接続ができるようになりました。
どちらか片方だけで試したときはダメそうでしたので、どうやらこの2点両方が必要そうという結論でまとめています。
(原因を詳しく調査したわけではないので、帰納的な結論です。)
※余談ですが、ESLintによって文末のセミコロン禁止ルール(no-extra-semi)がかかっているので、
やや見辛いかもしれません。スミマセン。。
結果から見ると今回のケースは私の元々の実装方法がマズかった可能性が高いのですが、
備忘録として残しておきます。
この他にもWkWebView対応でハマった点がいくつかありますので、
次回以降の記事で紹介したいと思います。
SQLが学べる 関連連載リンク
データベースの基礎が学べるSQL基礎講座
SQL基礎 連載
練習問題を通じてSQL理解度アップの人気連載!
SQL練習問題集