web ViewでなんちゃってPWAを作ってみた。 ~javascript alert()が動かない~

PWAとは

..progressive web apps

とよばれるアプリケーションですね。詳しいことは割愛しますが。基本的には ブラウザ最強! ネイティブアプリいらなくね?????? というような思想(違う)というものです。。

ただ、iOSsafariでは、まだ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サクッとメモでした。