こんにちは、イノベーションオフィスの吉田です。
最近 Swift 4 で WKWebView を使う機会が有ったのでメモ的投稿です。
WebView を使うとアプリが簡単に作れて便利なのですが、 JavaScript の alert や confirm にデフォルトでは対応してくれていませんでした。
というわけでざっと調べてみたのですが Swift 4 で対応している記事が見つからなかったので書いてみました。
早速コードになります。
import UIKit
import WebKit
class ViewController: UIViewController, WKUIDelegate, WKNavigationDelegate {
let wkWebView1 = WKWebView()
override func viewDidLoad() {
super.viewDidLoad()
let urlString1 = "https://www.google.co.jp/"
let encodeUrlString1 = urlString1.addingPercentEncoding(withAllowedCharacters: NSCharacterSet.urlQueryAllowed)
let url1 = NSURL(string: encodeUrlString1!)
let request1 = NSURLRequest(url: url1! as URL)
let userAgentStr = "My Browser App"
wkWebView1.customUserAgent = userAgentStr
wkWebView1.uiDelegate = self
wkWebView1.navigationDelegate = self
wkWebView1.frame = view.frame
view.addSubview(wkWebView1)
wkWebView1.load(request1 as URLRequest)
}
func webView(_ webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping () -> Void) {
let alertController = UIAlertController(title: "", message: message, preferredStyle: .alert)
let otherAction = UIAlertAction(title: "OK", style: .default) {
action in completionHandler()
}
alertController.addAction(otherAction)
present(alertController, animated: true, completion: nil)
}
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)
}
func webView(_ webView: WKWebView, runJavaScriptTextInputPanelWithPrompt prompt: String, defaultText: String?, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (String?) -> Void) {
let alertController = UIAlertController(title: "", message: prompt, preferredStyle: .alert)
let okHandler: () -> Void = {
if let textField = alertController.textFields?.first {
completionHandler(textField.text)
} else {
completionHandler("")
}
}
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel) {
action in completionHandler("")
}
let okAction = UIAlertAction(title: "OK", style: .default) {
action in okHandler()
}
alertController.addTextField() { $0.text = defaultText }
alertController.addAction(cancelAction)
alertController.addAction(okAction)
present(alertController, animated: true, completion: nil)
}
}
WKUIDelegate を継承して、alert / confirm / prompt を引っ掛けてあげる感じですね。
参考になれば幸いです。
それでは。
書いた人:イノベーションオフィス 室長 吉田