web ViewでなんちゃってPWAを作ってみた。 ~javascript alert()が動かない~
PWAとは
..progressive web apps
とよばれるアプリケーションですね。詳しいことは割愛しますが。基本的には ブラウザ最強!
ネイティブアプリいらなくね?????? というような思想(違う)というものです。。
ただ、iOSのsafariでは、まだPWAの基盤になりうる、push通知やservice worker などがまだ実装されていないのです。
そこで今回はwebViewにしてみました。 その際のTipsを軽くまとめます。
javascript の alert関数や comfirm のウインドウが開かない
今回は該当のVC (WebViewを使っているVC) に対してWKUIDelegateを使いjavascriptがうまく動くように実装します。
extension SampleViewController: WKUIDelegate { // alertを表示する func webView(_ webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping () -> Void) { let alertController = UIAlertController(title: "", message: message, preferredStyle: .alert) let okAction = UIAlertAction(title: "OK", style: .default) { action in completionHandler() } alertController.addAction(okAction) present(alertController, animated: true, completion: nil) } // confirm dialogを表示する func webView(_ webView: WKWebView, runJavaScriptConfirmPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (Bool) -> Void) { let alertController = UIAlertController(title: "", message: message, preferredStyle: .alert) let cancelAction = UIAlertAction(title: "Cancel", style: .cancel) { action in completionHandler(false) } let okAction = UIAlertAction(title: "OK", style: .default) { action in completionHandler(true) } alertController.addAction(cancelAction) alertController.addAction(okAction) present(alertController, animated: true, completion: nil) } }
このようにすることで alert(), comfirm()が正常に動くようになります。
why ?
webViewは基本的にブラウザのWindowを一つしか描画しないようです。
しかしながらJavascriptを利用すると、ブラウザはalert用のwindowを新規に作成します。 つまり、本来であればブラウザの中に別のwindowを展開するのですが、webviewではそれが不可能なので、 swiftの alertViewを利用してalertを表示するようにします。
こうすることでwebViewにてjavascriptのalert, comfirmが動くようになります。
インジケータを出したい。
extension SampleViewController: WKNavigationDelegate { func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) { UIApplication.shared.isNetworkActivityIndicatorVisible = true showIndicator() } func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { UIApplication.shared.isNetworkActivityIndicatorVisible = false self.view = webView self.indicator.stopAnimating() } }
こうすることでwebViewの中でロードしている最中はstatus bar にてインジケータが出ます。
fumihumiサクッとメモでした。