iOS 9のUIWebView+jQuery Mobile(+Cordova)に関する問題のまとめ

iOS 9でCordovaアプリを開発する上での問題は、このシルバーウィーク中に2本既に書いています。

iOS 9のUIWebViewがとても残念らしいのでWKWebViewに対応したCordova iOS 4.0(未リリース)を試してみる
【未解決】Cordova iOS 4.0(未リリース)を試す(その2)

どちらも、iOS 9のUIWebViewがダメダメなので、代わりにWKWebViewを使うしかなさそうだという話に基づいています。

Cordova iOSも最新リリースになるはずの4.0ではWKWebViewが採用されるようなので、大勢としてはUIWebViewからWKWebViewに置き換わっていくのは間違いありません。(ただ、WKWebViewにはUIWebViewにはない制限もあるらしいので、それが致命的なものであれば少なくともiOS上ではハイブリッドアプリの命脈は絶ちきられることになりかねないのですが。。。)

ここでいま一度、iOS 9のUIWebViewにどういう問題があるのか、jQuery Mobile視点でまとめておこうと思います。

App Transport Securityは対応必須

jQuery Mobileとは直接の関係はないのですが、iOS 9から新たに加わったセキュリティ機能であるApp Transport Securityは、HTTPでの通信が禁止されるのでXHRがことごとく失敗するので問題です。

ただ、これは回避策があって、下記の設定をInfo.plistに加えればHTTP通信ができるようになります。

[xml]
NSAppTransportSecurity

NSAllowsArbitraryLoads

[/xml]

window.historyがボロボロ

iOS 9のUIWebViewでは、window.historyがまともに機能しません。
jQuery Mobileにおいては、ヘッダ部に配置するBackボタンや、ダイアログのcloseに大きな影響を及ぼします。

hashListeningEnabledをfalseにする

Stack overflowのProblems with window.history using JQuery/Javascript on Cordova app in IOS9というディスカッションにあるように、下記のコードを追加することで多少の改善が得られます。


$(document).on("mobileinit", function() {
  $.mobile.hashListeningEnabled = false;
}

jQuery Mobile 1.4.5(現在の最新版)において、例えばmobile.pagecontainerのgoメソッドは下記のようなコードです。


go: function( steps ) {

	//if hashlistening is enabled use native history method
	if ( $.mobile.hashListeningEnabled ) {
		window.history.go( steps );
	} else {

		//we are not listening to the hash so handle history internally
		var activeIndex = $.mobile.navigate.history.activeIndex,
			index = activeIndex + parseInt( steps, 10 ),
			url = $.mobile.navigate.history.stack[ index ].url,
			direction = ( steps >= 1 )? "forward" : "back";

		//update the history object
		$.mobile.navigate.history.activeIndex = index;
		$.mobile.navigate.history.previousIndex = activeIndex;

		//change to the new page
		this.change( url, { direction: direction, changeHash: false, fromHashChange: true } );
	}
},

hashListeningEnabledがtrueの場合、window.history.goで処理するので、iOS 9のUIWebViewではまともに動作しません。
一方、mobileinitでhashListeningEnabledをfalseに変更しておいた場合、jQuery Mobile独自の仕組みで処理が行われます。window.historyに頼らないので正常に動作しそうです。

しかし、そうも上手くいきません。
少なくとも、私が試した限りでは、下記のような動作がありました。

例えば、下記のような3ページ構成のアプリがあったとします。
jQuery MobileではSPA(Single Page Architecture)で複数ページを構成するのが定石なので、ありふれた構造でしょう。

  • トップページ(index.html)
  • ページ1(index.html#page1)
  • ページ2(index.html#page2)

ここで、トップページ→ページ1→トップページ→ページ2のように遷移した場合、$.mobile.navigate.historyにどのようにスタックされるでしょうか。

  1. index.html
  2. #page1
  3. index.html
  4. #page2

であれば嬉しいのですが、実際にはこのようになります。(少なくとも、なることがあります)

  1. index.html
  2. #page1
  3. #page2

では、ページ2から戻る遷移(Backボタンやダイアログを閉じる)があると、UIWebViewにはどの画面が表示されるでしょうか。
望ましいのはトップページですが、実際には予想どおりページ1が表示されます。

考えられる解決策

安直ですが、window.historyや$.mobile.navigate.historyに依存しない画面遷移を行えば、この問題は解決しそうです。
つまり、Backさせるのではなく、遷移先(戻り先)の画面を直接指定してしまうのです。

ただ、それが難しそうな場面も予想されます。例えば、ダイアログです。
jQuery Mobileではダイアログも1つの画面に過ぎません。ダイアログの表示は単なるポップアップではなく、画面が遷移しているのです。そのため、ダイアログを閉じるということは前の画面に戻るということと同義です。
jQuery Mobileにおけるdialogのcloseメソッドは、内部的に上記のmobile.pagecontainerのgoメソッドを使用するので、closeメソッドを使う以上、この問題は避けられないのです。

jQuery Mobileとしてはバグではない

jQuery MobileのGitHubで、1.4.5 – ios9 window.history.back or link does not workというIssueが報告されています。

それに対する回答は下記のようなもので、このIssueはクローズされてしまいました。

1 4 5 ios9 window history back or link does not work Issue 8254 jquery jquery mobile

“Closing because not a bug.”

そら、そうやけどな。

一方で、下記のような回答もあります。

We solved the problem, if someone googles it, the solutions is to use WKWebview instead of the UIWebview.
So it was not a jquery mobile problem, sorry for the trouble.

なるほど。結局、UIWebViewは諦めてWKWebView使うしかないのか。。。

iOS 9.0.1でどうにかならないのか?

別件ですが、iOS 9には「スライドでアップグレード」問題というのがあって、これはAppleも公式に認めています。
その対応として、iOSアップデート(iOS 9.0.1)がまもなくリリースされるということになっています。

Ios9bug
https://support.apple.com/ja-jp/HT205239

iOS 9.0.1での改善内容が、さすがにこの問題1つだけということはないと思うので、それでUIWebViewも問題も治ったりしないかなと期待したいところですが。。。微かな微かな期待を。。。

【続報(2015/9/24)】
本日、iOS 9.0.1のバージョンアップが始まりましたが、UIWebViewの動きにはとくに違いがないようです。残念。。。

WKWebViewに移行するしか

結局、UIWebViewのことはきれいさっぱり忘れて、WKWebViewに移行するしかないのか。
Cordova iOSはまだリリースされていないけどWKWebViewへの移行を進めているわけだし、その流れに乗るしかないのかもしれません。

9月中にリリースされるというCordova iOS 4.0の出来に期待したい!(としか、言えない。)

この記事を書いた人

井上 研一

経済産業省推進資格ITコーディネータ/ITエンジニア/ブロガー。
井上研一事務所代表、株式会社ビビンコ代表取締役、一般社団法人ITC-Pro東京理事。
北九州市出身、横浜市在住。 AIやIoTに強いITコーディネータとして活動中。著書に「初めてのWatson」、「ワトソンで体感する人工知能」など。セミナーや研修講師での登壇も多数。

この記事が気に入ったら
いいね!しよう

最新の情報をお届けします