'Catch and call telephone number in WKWebView

I have a WKWebView that I want to ask to call a number when the number is selected. The contents of the web view contain the HTML anchor tag "tel:" and i am looking for a way to catch it. Which function is used to catch these tags?



Solution 1:[1]

Set the webView's navigationDelegate property and implement the following function of the delegate (WKNavigationDelegate)

func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
    if navigationAction.request.url?.scheme == "tel" {
        UIApplication.shared.open(navigationAction.request.url!)
        decisionHandler(.cancel)
    } else {
        decisionHandler(.allow)
    }
}
    

Since iOS 10, you can also set dataDetectorTypes to .phoneNumber on your WKWebViewConfiguration. All detected phone numbers will transformed to contain links around the phone number and thus the above function will be fired with a URL with a "tel" scheme when tapping on a phone number.

configuration.dataDetectorTypes = .phoneNumber

Solution 2:[2]

Fixed to make phone call in WKWebView by using the "decidePolicyFor navigationAction" delegate method:

func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
    if navigationAction.request.url?.scheme == "tel" {
        UIApplication.shared.openURL(navigationAction.request.url!)
        decisionHandler(.cancel)
    } else {
        decisionHandler(.allow)
    }
}

When setting up your web view set the data detector type on its configuration:

if #available(iOS 10.0, *) {
    webView.configuration.dataDetectorTypes = .phoneNumber
}

Solution 3:[3]

Swift4

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

if navigationAction.targetFrame == nil {

webView.load(navigationAction.request)

}

if navigationAction.request.url?.scheme == "tel" {

UIApplication.shared.openURL(navigationAction.request.url!)

decisionHandler(.cancel)

}

else if navigationAction.request.url?.scheme == "mailto" {

UIApplication.shared.openURL(navigationAction.request.url!)

decisionHandler(.cancel)

}

else{

decisionHandler(.allow)

}

}

You can also see this example for your reference. It works on real devices 100%

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Michal Šrůtek
Solution 2 shim
Solution 3 TAN