Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detect when a link is clicked in a WKWebView

How do you detect when a link was clicked in a WKWebView? I'm looking for the equivalent of this in a UIWebView.

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
    if(navigationType == UIWebViewNavigationTypeLinkClicked)
    {

    }
    return YES;
}

I tried this in the WKNavigationDelegate but I only ever get WKNavigationTypeOther for all requests even when clicking on links.

- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
{
    if(navigationAction.navigationType == WKNavigationTypeLinkActivated)
    {

    }
    decisionHandler(WKNavigationActionPolicyAllow);
}
like image 385
Berry Blue Avatar asked Mar 16 '16 21:03

Berry Blue


People also ask

What is the difference between UIWebView and WKWebView?

Unlike UIWebView, which does not support server authentication challenges, WKWebView does. In practical terms, this means that when using WKWebView, you can enter site credentials for password-protected websites.

How do I debug Safari WKWebView?

Debugging with WKWebViewOpen Safari and press ⌘+, to open Preference, under the Advanced tab, check “Show Develop menu in menu bar”. Not until we have the project build can we use the Safari debugger. The debugger is under Develop → Your simulator or device.

What browser is WKWebView?

WKWebView. WKWebView was introduced in iOS 8 allowing app developers to implement a web browsing interface similar to that of mobile Safari. This is due, in part, to the fact that WKWebView uses the Nitro Javascript engine, the same engine used by mobile Safari.

How do I know if WKWebView finish loading in Swift?

To check if your WKWebView has loaded easily implement the following method: import WebKit import UIKit class ViewController: UIViewController, WKNavigationDelegate { let webView = WKWebView() func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!)


1 Answers

What you can do in a WkWebView is the following:

override func viewDidLoad() {
    super.viewDidLoad()

     let webView = WKWebView()
     self.view.addSubview(webView) // you need to also setup constraints here - I left out for clarity
     // Make sure you set the delegate, so you get the callback
     self.webView.navigationDelegate = self
}

 // WKWebViewNavigationDelegate
 func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
     guard let url = navigationAction.request.url, let scheme = url.scheme, scheme.contains("http") else {
            // This is not HTTP link - can be a local file or a mailto
            decisionHandler(.cancel)
            return
        }
     // This is a HTTP link
     open(url: url)
     decisionHandler(.allow)
}

In this delegate method, you get the URL request that the WKWebView is trying to open. There you can check the attributes of the URLRequest and respond accordingly.

You can even write an extension for URLRequest that handles that logic, so you can reuse it.

extension URLRequest {
    var isHttpLink: Bool {
        return self.url?.scheme?.contains("http") ?? false
    }
}

Then you can change the long condition in the delegate method to:

 // WKWebViewNavigationDelegate
 func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
   guard navigationAction.request.isHttpLink else {
        decisionHandler(.allow)
        return
    }
   // ... handle url
like image 180
Catalina T. Avatar answered Sep 20 '22 22:09

Catalina T.