ポップアップが表示されないと言われたときの可能性

ポップアップにも色々ありますが、ここでは「リンクをタップするなどして、別ウィンドウで表示すること」のこととしています。 大抵の場合は target="_blank" のリンクだな……と推測できます。 しかしながら、そのウィンドウを開くイベントがJavaScriptから発生した場合は、別途、WKWebView側に設定する必要がありました……。

JavaScriptからウィンドウを開けるようにする

WKWebViewに対して、以下の設定をする必要がありました。

let preferences = WKPreferences()
preferences.javaScriptCanOpenWindowsAutomatically = true  // ここが重要

let configuration = WKWebViewConfiguration()
configuration.preferences = preferences

webView = WKWebView(frame: .zero, configuration: configuration)

これで、JavaScriptから新しいタブを開けるようになりました。

新しいWebViewを開かずに、既存のWebViewで読み込ませる

アプリ内で使用しているWKWebViewでは「新しいタブ」をサポートできない場合もあります。 その場合は、 target=_blankのときと同じようにWKUIDelegateを、以下のように実装します。

メソッドの引数が多いので、改行しています。

extension MyWebViewViewController: WKUIDelegate {
    func webView(_ webView: WKWebView,
                 createWebViewWith configuration: WKWebViewConfiguration,
                 for navigationAction: WKNavigationAction,
                 windowFeatures: WKWindowFeatures) -> WKWebView? {
        guard let url = navigationAction.request.url else { return nil }

        guard let targetFrame = navigationAction.targetFrame, targetFrame.isMainFrame else {
            let request = URLRequest(url: url)
            webView.load(url)
            return nil
        }

        return nil
    }
}

本来は新しいタブを開くときに呼ばれるメソッド(返り値がWKWebViewになっている)ですが、 ここでは、すでにあるWebViewで読み込むように実装し、新しいWebViewは返さないようにしています。

あとは、この実装したWKUIDelegateを、webViewにセットしておけばOK。

webView.uiDelegate = self  // selfにWKUIDelegateを実装している場合

これで完成!


ブラウザなら当たり前にできると思っていることも、アプリのWebViewで対応するときは手作業で設定するものが多いですね……。 しかも意外と、そのオプションたちに気づきにくいという……。