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
Uiimagejpegrepresentation Has Been Replaced by Instance Method Uiimage.Jpegdata(Compressionquality:)
How to Change the App Store's Large Icon on Itunes Connect
iPad - Parsing an Extremely Huge JSON - File (Between 50 and 100 Mb)
Perform UI Changes on Main Thread Using Dispatch_Async or Performselectoronmainthread
(iOS + Storekit) How to Detect When I'm in the Sandbox
How to Check If Haptic Engine (Uifeedbackgenerator) Is Supported
Is the Current Location/Compass Heading Button Available in the iOS Sdk
Share Video on Twitter with Fabric API Without Composer iOS
Loading a Welcome Screen (Splash Screen) Before Tabbarcontroller
App Crashing When Using Firebase Auth, Reason: 'Default App Has Already Been Configured.'
Trouble Creating Xmpp Muc Room: Code 503 (Service Unavailable)
How to Activate Tcp Keepalive on Apple iOS Devices
Disable Autolayout Localization Behavior (Rtl - Right to Left Behavior )
Calling Function from Another Viewcontroller in Swift
How to Check If the iOS Device Is Locked/Unlocked Using Swift