WKWebView - Javascript确认和警报无法正常工作

时间:2015-12-09 17:36:40

标签: javascript ios swift webview wkwebview

我正在使用WKWebView打开example.com,在那里我有一个测试链接,它应该打开一个JS警报,但我不能让它显示在设备上,它只有在我工作时才有效从浏览器查看网站。

我正在使用WKUIDelegate,并将这段代码添加到ViewController.swift文件中:

func webView(webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: (() -> Void)) {

    NSLog("Hello")
}

当我点击产生JS警报的链接时,我在XCode控制台中看不到任何内容。

我错过了什么?

3 个答案:

答案 0 :(得分:13)

您还需要在WKWebView上设置uiDelegate。

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)
    }
}

对于confirm()prompt(),请参阅其他委托方法。

答案 1 :(得分:12)

有点晚了,但我想补充一下我的经验,以备将来参考。当我尝试使用 Swift 3 和IOS 10时,@ Bon Bon的答案让我走上了解决方案的道路,在这种情况下,代码需要进行一些修改。 首先,您还需要实现WKUIDelegate,因此请将其添加到ViewController声明:

class ViewController: UIViewController, WKUIDelegate {

然后,当您实例化WKWebView对象时,例如:

self.webView = WKWebView(frame: self.view.frame)

您还需要将正确的值分配给实例的uiDelegate属性:

self.webView?.uiDelegate = self

最后你可以使用@Bon Bon提供的代码,但请注意Swift 3需要一些小的差异,例如presentViewController方法的名称变为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: .actionSheet)

    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)
}

这使得alertconfirmationtext inputWKWebView内正常工作,而 Xcode 8 中没有任何编译器警告。我不是专家Swift程序员,因此非常感谢任何有关代码正确性的有用评论。

答案 2 :(得分:6)

以下是Swift中各种javascript警报实现的示例代码:

所有关于将javascript警报中的信息转换为原生UI ,并调用completionHandler()将用户操作发送回javascript引擎。

$resume_contact_methods = array();
$i = 0;
foreach( $data['resume_contact_method'] as $resume_contact_method ) {
    if($resume_contact_method != '') {
        $resume_contact_methods[] = $data['resume_contact_method'][$i];
    }
    $i++;
}

$meta_input = array(
    'resume_contact_method' => $resume_contact_methods,
);