Launching Phone/Email/Map Links in Wkwebview

WKWebView issues with tel: links

Managed to find a solution finally:

import UIKit
import WebKit

class ViewController: UIViewController, WKNavigationDelegate, WKUIDelegate{

@IBOutlet weak var webView: WKWebView!

override func viewDidLoad() {
webView.navigationDelegate = self
webView.uiDelegate = self
super.viewDidLoad()
let htmlpath = Bundle.main.path(forResource: "index", ofType: "html")
let url2 = URL(fileURLWithPath: htmlpath!)
let request = URLRequest(url: url2)
webView.load(request)
webView.scrollView.bounces = false
//webview.configuration.dataDetectorTypes = .phoneNumber
}

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)
}
}

Using this seems to pick up the tel: links fine, an answer I found on here previously didn't have the else statement so fired decisionHandler more than once which created the error, the else statement fixed that and now seems fine.

WKWebView: mailto links in html content not opening mail app

One way to do what you want would be to implement WKNavigationDelegate:

import UIKit
import WebKit

class ViewController: UIViewController {

@IBOutlet weak var webView: WKWebView!

override func viewDidLoad() {
super.viewDidLoad()

guard
let file = Bundle.main.path(forResource: "test", ofType: "html"),
let html = try? String(contentsOfFile: file) else {
return
}

webView.navigationDelegate = self
webView.loadHTMLString(html, baseURL: nil)
}

@IBAction func didTapButton(_ sender: Any) {
let email = "email@email.com"
guard
let url = URL(string: "mailto:\(email)") else {
return
}

UIApplication.shared.open(url, options: [:], completionHandler: nil)
}
}

extension ViewController: WKNavigationDelegate {
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction,
decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
guard
let url = navigationAction.request.url,
let scheme = url.scheme else {
decisionHandler(.cancel)
return
}

if (scheme.lowercased() == "mailto") {
UIApplication.shared.open(url, options: [:], completionHandler: nil)
// here I decide to .cancel, do as you wish
decisionHandler(.cancel)
return
}
decisionHandler(.allow)
}
}

Here you have a ViewController that has webView as an outlet, this WKWebView would load an html file like this:

<a href="mailto:email@email.com">Mail me</a>

And I also added in storyboard a button just for reference, which would have the IBAction didTapButton described above.

The key here is:

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

Which would give you the URL and let you decide what policy is suitable for it. Here I check if it contains mailto: as I already know this is what you're interested in so if it does, I simply open the URL as I would do if the user presses an UIButton visible on screen.

Hope it helps, cheers!

LE: Make sure you run on a real device (simulators don't have Mail app installed), also make sure you have the Mail app installed, cause I didn't..

WKWebView open links from certain domain in safari

You can implement WKNavigationDelegate, add the decidePolicyForNavigationAction method and check there the navigationType and requested url. I have used google.com below but you can just change it to your domain:

Xcode 8.3 • Swift 3.1 or later

import UIKit
import WebKit

class ViewController: UIViewController, WKNavigationDelegate {

let webView = WKWebView()

override func viewDidLoad() {
super.viewDidLoad()

webView.frame = view.bounds
webView.navigationDelegate = self

let url = URL(string: "https://www.google.com")!
let urlRequest = URLRequest(url: url)

webView.load(urlRequest)
webView.autoresizingMask = [.flexibleWidth,.flexibleHeight]
view.addSubview(webView)
}

func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
if navigationAction.navigationType == .linkActivated {
if let url = navigationAction.request.url,
let host = url.host, !host.hasPrefix("www.google.com"),
UIApplication.shared.canOpenURL(url) {
UIApplication.shared.open(url)
print(url)
print("Redirected to browser. No need to open it locally")
decisionHandler(.cancel)
return
} else {
print("Open it locally")
decisionHandler(.allow)
return
}
} else {
print("not a user click")
decisionHandler(.allow)
return
}
}
}


Related Topics



Leave a reply



Submit