133

I'm migrating from UIWebView to WKWebView, how can I rewrite these function for WKWebView?

func webViewDidStartLoad(webView: UIWebView){}
func webViewDidFinishLoad(webView: UIWebView){}

and

func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool {
    print("webview asking for permission to start loading")
    if navigationType == .LinkActivated && !(request.URL?.absoluteString.hasPrefix("http://www.myWebSite.com/exemlpe"))!{
        UIApplication.sharedApplication().openURL(request.URL!)
        print(request.URL?.absoluteString)
        return false
    }
    print(request.URL?.absoluteString)
    lastUrl = (request.URL?.absoluteString)!

    return true
}


func webView(webView: UIWebView, didFailLoadWithError error: NSError?) {
    print("webview did fail load with error: \(error)")
    let testHTML = NSBundle.mainBundle().pathForResource("back-error-bottom", ofType: "jpg")
    let baseUrl = NSURL(fileURLWithPath: testHTML!)
        
    let htmlString:String! = "myErrorinHTML"
    self.webView.loadHTMLString(htmlString, baseURL: baseUrl)
}
2

3 Answers 3

256

UIWebView => WKWebView Equivalent

UIWebViewDelegate => WKNavigationDelegate

delegate => navigationDelegate
didFailLoadWithError => didFailNavigation
webViewDidFinishLoad => didFinishNavigation
webViewDidStartLoad => didStartProvisionalNavigation
shouldStartLoadWithRequest => 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)
}
Sign up to request clarification or add additional context in comments.

5 Comments

webViewDidFinishLoad and didFinishNavigation are not exactly the same. The didFinishNavigation method is called before the page is fully loaded.
documentation says that this method is for osx only. The question was for iOS
@Gargo Take a look to both the descriptions: webViewDidFinishLoad , didFinishNavigation , as you see is available also for iOS 8.0+
stackoverflow.com/questions/46171410/… - anyone help me this issue @AlessandroOrnano
Just short note that these methods are declared in WKNavigationDelegate (notWKUIDelegate).
43

Here is the Objective-C methods for the migration:

  1. 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);
}
  1. webViewDidStartLoad -> didStartProvisionalNavigation
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation {
}
  1. webViewDidFinishLoad -> didFinishNavigation
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {
}
  1. didFailLoadWithError -> didFailNavigation
- (void)webView:(WKWebView *)webView didFailNavigation:(WKNavigation *)navigation withError:(NSError *)error {
}

1 Comment

should that be WKNavigationTypeLinkActivated rather than UIWebViewNavigationTypeLinkClicked?
16

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.open(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))
}

1 Comment

Small update: in shouldStartLoadWithRequest function, openURL(url) has been deprecated. It is not just open(url)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.