2

WKWebView 几个不常用的特性

 2 years ago
source link: https://mp.weixin.qq.com/s/FFZMz9Yc2Bm6-gAnCBsUZw
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

WKWebView 几个不常用的特性

The following article is from 知识小集 Author Anupam Chugh

网罗开发
网罗开发
网罗天下方法,方便你我开发。「网罗开发」以移动端技术分享为核心,包含 iOS、Android、前端、小程序、RN、后端、算法等技术,认真总结相关技术,每天 17:01 准时推送!
99篇原创内容
Official Account

作者 | Anupam Chugh 
来源 | Better Programming,点击“阅读原文”查看作者更多文章

iOS 中对 Web 的支持可以分为两个阶段:UIWebView 以及后来的 WKWebView。自 iOS 12 起,UIWebView 就开始被弃用。而在不久的将来,Apple 甚至不接受带有 UIWebView 的应用程序提交。

WKWebView 是 WebKit 框架的一部分,在应用程序的主线程之外运行,从而有助于其稳定性和卓越的性能。

首先,要加载内容,我们只需执行以下操作:

guard let url = URL(string: string) else { return }
let request = URLRequest(url: url)
webView?.load(request)

除了内容加载和 CSS 样式外,WKWebView 还可以做很多事情。

以下部分是 WKWebView 相对用得较少的一些功能清单。

1.截获 Web URL

通过实现 WKNavigationDelegate 协议的 definePolicyFor 函数,我们可以在导航期间截获 URL。以下代码段显示了如何完成此操作:

func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
let urlString = navigationAction.request.url?.absoluteString ?? ""
let pattern = "interceptSomeUrlPattern"
if urlString.contains(pattern){
var splitPath = urlString.components(separatedBy: pattern)
}
}

2. JavaScript Alert

默认情况下,来自 JavaScript 的提示不会显示在 WKWebView 中,因为它不是 UIKit 的一部分。因此,我们需要实现 WKUIDelegate 协议,以便显示提示信息中的警告、确认或文本输入等。

以下几种提示类型对应的方法:

func webView(_ webView: WKWebView, runJavaScriptConfirmPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (Bool) -> Void)

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


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

self.present(alertController, animated: true, completion: nil)
}
640?wx_fmt=gif

3.配置URL操作

使用 decisionPolicyFor 函数,您不仅可以通过电话,facetime 和邮件等操作来控制外部导航,还可以选择限制某些 URL 的打开。以下代码展示了每种情况:

func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {

guard let url = navigationAction.request.url else {
decisionHandler(.allow)
return
}

if ["tel", "sms", "mailto"].contains(url.scheme) && UIApplication.shared.canOpenURL(url) {
UIApplication.shared.open(url, options: [:], completionHandler: nil)
decisionHandler(.cancel)
} else {
if let host = navigationAction.request.url?.host {
if host == "www.notsafeforwork.com" {
decisionHandler(.cancel)
}
else{
decisionHandler(.allow)
}
}
}
}
}

4.使用 WKWebView 进行身份验证

当 WKWebView 中的 URL 需要用户授权时,您需要实现以下方法:

func webView(_ webView: WKWebView, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {

let authenticationMethod = challenge.protectionSpace.authenticationMethod
if authenticationMethod == NSURLAuthenticationMethodDefault || authenticationMethod == NSURLAuthenticationMethodHTTPBasic || authenticationMethod == NSURLAuthenticationMethodHTTPDigest {
//Do you stuff
}
completionHandler(NSURLSessionAuthChallengeDisposition.UseCredential, credential)
}

收到身份验证质询后,您可以确定所需的身份验证类型(用户凭据或证书),并相应地使用提示或预定义凭据来处理条件。

5.多个 WKWebView 共享 Cookie

WKWebView 的每个实例都有其自己的 cookie 存储。为了在 WKWebView 的多个实例之间共享 cookie,我们需要使用 WKHTTPCookieStore,如下所示:

let cookies = HTTPCookieStorage.shared.cookies ?? []
for (cookie) in cookies {
webView.configuration.websiteDataStore.httpCookieStore.setCookie(cookie)
}

6.获取加载进度

WKWebView 的其他功能非常普遍,例如显示正在加载的 URL 的进度更新。

可以通过侦听以下方法的 estimatedProgress 的 keyPath 值来更新 ProgressViews:

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?)

-End-

WKWebview 加载过程中的性能指标图解
WKWebview 秒开的实践及踩坑之路
用 Swift 写一个自动打包 ipa,并上传蒲公英

领取面试题

640?wx_fmt=png

640?wx_fmt=jpeg

进入上方二维码内 回复「面试题」

在看点这里640?wx_fmt=gif好文分享给更多人↓↓


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK