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サクッとメモでした。