Migrating from UIWebView to WKWebView
UIWebView => WKWebView Equivalent
UIWebViewDelegate => WKNavigationDelegatedelegate => navigationDelegatedidFailLoadWithError => didFailNavigationwebViewDidFinishLoad => didFinishNavigationwebViewDidStartLoad => didStartProvisionalNavigationshouldStartLoadWithRequest => decidePolicyForNavigationAction
About shouldStartLoadWithRequest
you can write:
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) { print("webView:\(webView) decidePolicyForNavigationAction:\(navigationAction) decisionHandler:\(decisionHandler)") switch navigationAction.navigationType { case .linkActivated: if navigationAction.targetFrame == nil { self.webView?.loadRequest(navigationAction.request) } if let url = navigationAction.request.url, !url.absoluteString.hasPrefix("http://www.myWebSite.com/example") { UIApplication.shared.open(url) print(url.absoluteString) decisionHandler(.cancel) return } default: break } if let url = navigationAction.request.url { print(url.absoluteString) } decisionHandler(.allow)}
And for the didFailLoadWithError
:
func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) { print("webView:\(webView) didFailNavigation:\(navigation) withError:\(error)") let testHTML = Bundle.main.path(forResource: "back-error-bottom", ofType: "jpg") let baseUrl = URL(fileURLWithPath: testHTML!) let htmlString = "myErrorInHTML" self.webView.loadHTMLString(htmlString, baseURL: baseUrl)}
Here is the Objective-C methods for the migration:
- shouldStartLoadWithRequest -> decidePolicyForNavigationAction
Remember to call the decisionHandler
:
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler { if (navigationAction.navigationType == WKNavigationTypeLinkActivated) { } NSString *url = [navigationAction.request.URL query]; decisionHandler(WKNavigationActionPolicyAllow);}
- webViewDidStartLoad -> didStartProvisionalNavigation
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation {}
- webViewDidFinishLoad -> didFinishNavigation
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {}
- didFailLoadWithError -> didFailNavigation
- (void)webView:(WKWebView *)webView didFailNavigation:(WKNavigation *)navigation withError:(NSError *)error {}
Migrating UIWebView to WKWebView, Swift 4:
Equivalent of shouldStartLoadWithRequest
:
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) { var action: WKNavigationActionPolicy? defer { decisionHandler(action ?? .allow) } guard let url = navigationAction.request.url else { return } print(url) if navigationAction.navigationType == .linkActivated, url.absoluteString.hasPrefix("http://www.example.com/open-in-safari") { action = .cancel // Stop in WebView UIApplication.shared.openURL(url) // Open in Safari }}
Equivalent of webViewDidStartLoad
:
func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) { print(String(describing: webView.url))}
Equivalent of didFailLoadWithError
:
func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) { let nserror = error as NSError if nserror.code != NSURLErrorCancelled { webView.loadHTMLString("404 - Page Not Found", baseURL: URL(string: "http://www.example.com/")) }}
Equivalent of webViewDidFinishLoad
:
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { print(String(describing: webView.url))}