簡易的なタブブラウザーをSwiftで作っていてjavascriptのwindow.close()が効かない時があり、ハマったので解決法をメモ。
webViewDidCloseが呼ばれない
通常であればWKUIDelegateをデリゲートしていれば、ブラウザが閉じるタイミングでwebViewDidClose()が呼ばれるはずだけど、呼ばれない場合がある。※ブラウザという性質上、web側のjsは弄れず様々な書式で描かれている事が前提。
<a href="javascript:void(0);" onclick="window.close();">閉じる</a>
func webViewDidClose(_ webView: WKWebView) {
print("Window close")
}
呼ばれない物の共通点として動的に生成されたコードのイベント処理などがWKUIDelegateで拾えない気がしている。
[解決策] WKScriptMessageHandlerを使う
windowがloadされる前に用意したjsを読み込む
(function () {
var _close = window.close;
window.close = function () {
webkit.messageHandlers.windowClose.postMessage(null);
_close();
};
})();
//classにWKScriptMessageHandlerを追加
//WKWebViewConfigurationにuserscript追加
let webViewConfiguration = WKWebViewConfiguration()
let userController:WKUserContentController = WKUserContentController()
//messageHandlersの名前を登録
//addScriptMessageHandler() => add()に変わったみたいです。
userController.add(self, name: "windowClose")
//windowがloadされる前にjsを追加
if let path = Bundle.main.path(forResource: "WindowClose", ofType: "js"){
if let source = try? NSString(contentsOfFile: path, encoding: String.Encoding.utf8.rawValue){
let userscript = WKUserScript(source: source as String,injectionTime:WKUserScriptInjectionTime.atDocumentEnd,forMainFrameOnly:true)
userController.addUserScript(userscript)
}
}
webViewConfiguration.userContentController = userController
let webView = WKWebView(frame: view.bounds, configuration: webViewConfiguration)
//window.closeが呼ばれた場合の処理
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
if(message.name == "windowClose") {
print("Window close")
}
}
//window.closeが呼ばれた場合の処理
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
if(message.name == "windowClose") {
print("Window close")
}
}
参考にさせて頂いたページ
Bug 1172928 - Window.close() does not close the tab
https://github.com/mozilla-mobile/firefox-ios/pull/758/files#diff-ae4b3ae1d0a0ca806a652b55ae38509a
[Swift] WKWebView で JavaScript をネイティブ側から実行する
http://qiita.com/takecian/items/9baf7e2bd611aac4791d
swift + javascript 値渡しでWKWebViewはすごかった
http://qiita.com/peta-m175/items/102d6d723fd87e722f83