WKWebView - Javascript Confirm And Alert Not Working
Solution 1:
A little late but I would like to add my experience for future reference. The answer of @Bon Bon brought me on the path to the solution while I was trying to make things work with Swift 3 and IOS 10, in which case the code needs some modifications.
Firstly you need to implement also WKUIDelegate, so add it to the ViewController declaration:
class ViewController: UIViewController, WKUIDelegate {
Then when you instantiate the WKWebView object, as for example like so:
self.webView = WKWebView(frame: self.view.frame)
you need also to assign the correct value to the uiDelegate property of the instance:
self.webView?.uiDelegate = self
Then finally you can use the code provided by @Bon Bon, but note that there are some little differences required by Swift 3, as for example, the name of the presentViewController method becomes present :
func webView(_ webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping () -> Void) {
let alertController = UIAlertController(title: nil, message: message, preferredStyle: .actionSheet)
alertController.addAction(UIAlertAction(title: "Ok", style: .default, handler: { (action) in
completionHandler()
}))
self.present(alertController, animated: true, completion: nil)
}
func webView(_ webView: WKWebView, runJavaScriptConfirmPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (Bool) -> Void) {
let alertController = UIAlertController(title: nil, message: message, preferredStyle: .actionSheet)
alertController.addAction(UIAlertAction(title: "Ok", style: .default, handler: { (action) in
completionHandler(true)
}))
alertController.addAction(UIAlertAction(title: "Cancel", style: .default, handler: { (action) in
completionHandler(false)
}))
self.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: nil, message: prompt, preferredStyle: .alert)
alertController.addTextField { (textField) in
textField.text = defaultText
}
alertController.addAction(UIAlertAction(title: "Ok", style: .default, handler: { (action) in
if let text = alertController.textFields?.first?.text {
completionHandler(text)
} else {
completionHandler(defaultText)
}
}))
alertController.addAction(UIAlertAction(title: "Cancel", style: .default, handler: { (action) in
completionHandler(nil)
}))
self.present(alertController, animated: true, completion: nil)
}
That made alert, confirmation and text input to work correctly within WKWebView, without any compiler warning in Xcode 8. I'm not an expert Swift programmer, so any useful comment about correctness of the code would be very appreciated.
Solution 2:
You also need to set the uiDelegate on the WKWebView.
import UIKit
import WebKit
class ViewController: UIViewController, WKUIDelegate, WKNavigationDelegate {
var wkWebView: WKWebView!
public override func viewDidLoad() {
super.viewDidLoad()
wkWebView = WKWebView(frame: view.bounds, configuration: WKWebViewConfiguration())
wkWebView.uiDelegate = self
wkWebView.navigationDelegate = self
view.addSubview(wkWebView!)
let url = URL(string: "https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_alert")!
wkWebView.load(URLRequest(url: url))
}
func webView(_ webView: WKWebView,
runJavaScriptAlertPanelWithMessage message: String,
initiatedByFrame frame: WKFrameInfo,
completionHandler: @escaping () -> Void) {
let alert = UIAlertController(title: nil, message: message, preferredStyle: .alert)
let title = NSLocalizedString("OK", comment: "OK Button")
let ok = UIAlertAction(title: title, style: .default) { (action: UIAlertAction) -> Void in
alert.dismiss(animated: true, completion: nil)
}
alert.addAction(ok)
present(alert, animated: true)
completionHandler()
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
wkWebView.evaluateJavaScript("alert('Hello from evaluateJavascript()')", completionHandler: nil)
}
}
For confirm() and prompt() see the other delegate methods.
Solution 3:
Here is a sample code for various javascript alert implementation in Swift:
It's all about converting info in javascript alert into native UI, and call the completionHandler() to send the user action back to javascript engine.
func webView(webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: () -> Void) {
let alertController = UIAlertController(title: nil, message: message, preferredStyle: .ActionSheet)
alertController.addAction(UIAlertAction(title: "Ok", style: .Default, handler: { (action) in
completionHandler()
}))
self.presentViewController(alertController, animated: true, completion: nil)
}
func webView(webView: WKWebView, runJavaScriptConfirmPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: (Bool) -> Void) {
let alertController = UIAlertController(title: nil, message: message, preferredStyle: .ActionSheet)
alertController.addAction(UIAlertAction(title: "Ok", style: .Default, handler: { (action) in
completionHandler(true)
}))
alertController.addAction(UIAlertAction(title: "Cancel", style: .Default, handler: { (action) in
completionHandler(false)
}))
self.presentViewController(alertController, animated: true, completion: nil)
}
func webView(webView: WKWebView, runJavaScriptTextInputPanelWithPrompt prompt: String, defaultText: String?, initiatedByFrame frame: WKFrameInfo, completionHandler: (String?) -> Void) {
let alertController = UIAlertController(title: nil, message: prompt, preferredStyle: .ActionSheet)
alertController.addTextFieldWithConfigurationHandler { (textField) in
textField.text = defaultText
}
alertController.addAction(UIAlertAction(title: "Ok", style: .Default, handler: { (action) in
if let text = alertController.textFields?.first?.text {
completionHandler(text)
} else {
completionHandler(defaultText)
}
}))
alertController.addAction(UIAlertAction(title: "Cancel", style: .Default, handler: { (action) in
completionHandler(nil)
}))
self.presentViewController(alertController, animated: true, completion: nil)
}
Post a Comment for "WKWebView - Javascript Confirm And Alert Not Working"