Listed


WKWebView(一)--简介

简介 #

UIWebView是我们从iOS2.0就开始使用的web组件, 但是从iOS8.0以后, 苹果建议我们使用WKWebView, 那么他们之间有什么不同呢? WKWebView又怎么使用呢?

UIWebView是UIKit组件, 由于在项目刚开始构建的时候就已经默认引入了UIKit组件, 所以你可以任何地方声明UIWebView来使用都可以, 包括IB; WKWebView是WebKit组件, 在使用的时候要提前引入import WebKit

关于scalesPageToFit #

WKWebView不再包含scalesPageToFit属性, 但是可以通过在header中添加meta属性来控制

1
2
// width=device-width
<meta name="viewport" content="width=device-width,initial-scale=1, user-scalable=no" />

如果HTML文件不是本地文件,我们也可以通过WKUserScript将meta注入进去

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
let javaScript = """
    var meta = document.createElement('meta');
    meta.setAttribute('name', 'viewport');
    meta.setAttribute('content', 'width=device-width');
    document.getElementsByTagName('head')[0].appendChild(meta);
    """
    
let userScript = WKUserScript(source: javaScript, injectionTime: .atDocumentEnd, forMainFrameOnly: true)
let userController = WKUserContentController()
userController.addUserScript(userScript)
    
let webConfiguration = WKWebViewConfiguration()
webConfiguration.userContentController = userController

webView = WKWebView(frame: .zero, configuration: webConfiguration)
    
// let myURL = URL(fileURLWithPath: Bundle.main.path(forResource: "h5/index", ofType: "html")!)
let myURL = URL(string: "https://github.com")!
let myRequest = URLRequest(url: myURL)
webView.load(myRequest)
    
view = webView

白屏问题 #

UIWebView内存过大,会导致app crash, 由于WKWebView是运行在另一个进程里,内存过大不会导致整个app crash, 但是会导致页面白屏, 庆幸的时候我们可以通过WKNavigationDelegate的回调方法来处理白屏事件,收到事件后, 我们可以弹框提示, 或者及时刷新页面.

1
2
@available(iOS 9.0, *)
optional public func webViewWebContentProcessDidTerminate(_ webView: WKWebView)

Cookies问题 #

网上流传一种说法: WKWebView加载网页得到的Cookie会同步到NSHTTPCookieStorage中, 但接下来的请求不会自动携带Cookie. 但是目前测试下来,cookie是会带上的,WKWebView中登录github.com,然后杀掉进程,再次进入,依然是登录状态,通过safari的develop菜单,可以看到cookie的信息. 如果说真的不自动携带cookie, 我们也可以通过setValue:forHTTPHeaderField:和WKUserScript注入的形式,将cookie写入进去.

参考资料 #

uiwebview wkwebview
stackoverflow.com
medium.com
mp.weixin.qq.com