这儿每天共享一个 iOS 的新知识,快来重视我吧

前语

在现在的开发中,要将 H5 页面展现在 App 中首要用到 WKWebView。在 Web 网页中有一些经典的 Alert 弹窗,为了支撑这种警报,需求完成一些 WKWebView.uiDelegate 回调。这篇文章首要来讲讲如何在 iOS WKWebView 上支撑各种 Javascript 警报的代码示例:

UIDelegate

首要你的 webView 需求支撑 WKWebView.uiDelegate 协议,它包括支撑 Javascript 警报所需的办法。

webKitView?.uiDelegate = self

WKWebView Javascript 警报音讯

当 Web 上履行 window.alert 的时分,体系会调用 webView(_:, runJavaScriptAlertPanelWithMessage:, initiatedByFrame:, completionHandler:) 代理办法, 咱们需求在这个办法中做出接受:

func webView(_ webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping () -> Void) {
    let alert = UIAlertController(
        title: "这是一个来自 JS 的 Alert",
        message: "Alert 的内容为:(message)",
        preferredStyle: .alert
    )
    // 增加一个 完成 按钮
    let okAction = UIAlertAction(
        title: "完成",
        style: .default,
        handler: { _ in
            completionHandler()
        }
    )
    alert.addAction(okAction)
    present(alert, animated: true, completion: nil)
}

当 Web 上履行 window.alert('测验 alert') 的时分,就会调用这个办法,并弹出咱们的 UIAlertController

WKWebView 展现来自 JS 的正告信息

Javascript 承认操作

当在 js 中履行 window.confirm("message") 时就会调用 webView(_:, runJavaScriptConfirmPanelWithMessage:, initiatedByFrame:, completionHandler:) 办法,咱们能够在此阻拦,并自己弹出一个 UIAlertController 来让用户承认。

这个办法中的 completionHandler 来回调给 WebView 用户点了是或者否。

func webView(_ webView: WKWebView,
    runJavaScriptConfirmPanelWithMessage message: String,
    initiatedByFrame frame: WKFrameInfo,
    completionHandler: @escaping (Bool) -> Void) {
    // Set the message as the UIAlertController message
    let alert = UIAlertController(
        title: "这是一个来自 JS 的承认弹窗",
        message: "需求承认的内容为:(message)",
        preferredStyle: .alert
    )
    // 增加一个承认按钮
    let okAction = UIAlertAction(
        title: "承认",
        style: .default,
        handler: { _ in
            // 当用户点击承认,回调 true 给 webView
            completionHandler(true)
        }
    )
    alert.addAction(okAction)
    // 增加一个撤销按钮
    let cancelAction = UIAlertAction(
        title: "撤销",
        style: .cancel,
        handler: { _ in
            // 当用户点击撤销,回调 false 给 webView
            completionHandler(false)
        }
    )
    alert.addAction(cancelAction)
    present(alert, animated: true, completion: nil)
}

当 H5 上 js 调用 window.confirm("你承认吗?"),就会在页面上看到:

WKWebView 展现来自 JS 的正告信息

Javascript 输入提示

当在 js 中履行 window.prompt() 时就会调用 webView(_:, runJavaScriptTextInputPanelWithPrompt prompt:, defaultText:, initiatedByFrame frame:, completionHandler:) 办法,咱们能够在此阻拦,并自己弹出一个 UIAlertController 来让用户输入内容。

func webView(_ webView: WKWebView,
    runJavaScriptTextInputPanelWithPrompt prompt: String,
    defaultText: String?,
    initiatedByFrame frame: WKFrameInfo,
    completionHandler: @escaping (String?) -> Void) {
    let alert = UIAlertController(
        title: "这是一个来自 JS 的输入框弹窗",
        message: "提示词为:(prompt)",
        preferredStyle: .alert
    )
    // 增加一个输入框
    alert.addTextField()
    // 把默认值写进输入框
    alert.textFields?.first?.text = defaultText
    // 增加一个提交按钮
    let submitAction = UIAlertAction(
        title: "提交",
        style: .default,
        handler: { [unowned alert] _ in
            // 把用户输入的内容回调给 js
            let input = alert.textFields?.first
            completionHandler(input?.text)
        }
    )
    alert.addAction(submitAction)
    present(alert, animated: true, completion: nil)
}

当 js 履行 window.prompt('请输入内容', '这是输入框的默认值'),就会在页面上看到咱们自定义的带输入框的 Alert:

WKWebView 展现来自 JS 的正告信息

重要的一点

如果你决定使用这种方法接受 js 的警报弹窗,那么这三个办法的 completionHandler 回调一定要履行,否则当 js 调用到对应的办法时 App 会发生溃散,溃散日志为:

Terminating app due to uncaught exception
'NSInternalInconsistencyException', reason: 
'Completion handler passed to 
-[TestProject.ViewController webView:runJavaScriptAlertPanelWithMessage:initiatedByFrame:completionHandler:] 
was not called'

这儿每天共享一个 iOS 的新知识,快来重视我吧

本文同步自微信公众号 “iOS新知”,每天准时共享一个新知识,这儿仅仅同步,想要及时学到就来重视我吧!