How can I open external links in Swift webview?

2.1k Views Asked by At

I am totally new to Swift and I just need a webview app of my website. Everything seems fine except the external links such as "tel", "mailto", or "whatsapp". When I click them, nothing happens. I have searched many related titles and tried many things but the links are still not working. The last thing I tried is below. Can anyone help?


import UIKit
import WebKit

class ViewController: UIViewController, WKUIDelegate, WKNavigationDelegate {
    
    var webView: WKWebView!
    
    
    override func loadView() {
        let webConfiguration = WKWebViewConfiguration()
        webView = WKWebView(frame: .zero, configuration: webConfiguration)
        webView.uiDelegate = self
        view = webView
    }
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let myURL = URL(string:"https://www.sepettte.com")
        let myRequest = URLRequest(url: myURL!)
        webView.load(myRequest)
    }

    func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) {
      
      guard let failingUrlStr = (error as NSError).userInfo["NSErrorFailingURLStringKey"] 
      as? String  else { return }
      let failingUrl = URL(string: failingUrlStr)!

      switch failingUrl {
      
        case _ where failingUrlStr.hasPrefix("fb:"):
        if #available(iOS 10.0, *) {
           UIApplication.shared.open(failingUrl, options: [:], completionHandler: nil)
           return
        }
          
        case _ where failingUrlStr.hasPrefix("whatsapp:"):
        if UIApplication.shared.canOpenURL(failingUrl) {
          UIApplication.shared.open(failingUrl, options: [:], completionHandler: nil)
          return
        }

        case _ where failingUrlStr.hasPrefix("mailto:"):
        if UIApplication.shared.canOpenURL(failingUrl) {
          UIApplication.shared.open(failingUrl, options: [:], completionHandler: nil)
          return
        }
          
        case _ where failingUrlStr.hasPrefix("tel:"):
        if UIApplication.shared.canOpenURL(failingUrl) {
          UIApplication.shared.open(failingUrl, options: [:], completionHandler: nil)
          return
        }

      default: break
      }
    }
}

1

There are 1 best solutions below

9
RTXGamer On BEST ANSWER

Try intercepting requests on WKWebView implementing decidePolicyFor navigationAction :

class ViewController: UIViewController, WKNavigationDelegate {
    
    @IBOutlet weak var webView: WKWebView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        webView.uiDelegate = self
        webView.navigationDelegate = self

        webView.allowsBackForwardNavigationGestures = true

        let myURL = URL(string:"https://www.sepettte.com")
        let myRequest = URLRequest(url: myURL!)
        webView.load(myRequest)
    }
    
    func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: (WKNavigationActionPolicy) -> Void) {
        
        guard let redirectURL = (navigationAction.request.url) else {
            decisionHandler(.cancel)
            return
        }
        
        if (redirectURL.absoluteString.contains("tel:") ) {
            UIApplication.shared.open(redirectURL, options: [:], completionHandler: nil)
        }
        
        if (redirectURL.absoluteString.contains("whatsapp") ) {
            UIApplication.shared.open(redirectURL, options: [:], completionHandler: nil)
        }
        
        decisionHandler(.allow)
    }
}
extension ViewController: WKUIDelegate {

    func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
        
        guard let url = navigationAction.request.url else {
            return nil
        }
        
        guard let targetFrame = navigationAction.targetFrame, targetFrame.isMainFrame else {
            webView.load(URLRequest(url: url))
            return nil
        }
        return nil
    }
}

Output:

enter image description here