iOS Swift 4 WKWebview – Detect tel, mailto, target=”_blank” and CheckConnection

In this tutorial, we will show you how to develop a Webview  iOS application that can detect telephone links (tel:), email links (mailto:), handle new tab (target=”_blank”) and check for internet connection using WKWebView. As an additional features, I’ve used interactive page title and activity loader (preloader).

Please note, this code only works on real devices. 

Language: Swift 4
Software: Xcode 9.4
Testing
Classes: ViewController.swift, WebView.swift, CheckInternet.swift
CODE:

ViewController.swift

//

//ViewController.swift

//WKWebView

//

//Created by Tansu Canturk on 30/8/18.

//Copyright © 2018 Subz Designs. All rights reserved.

//

import UIKit

class ViewController: UIViewController {

override func viewDidLoad() {

super.viewDidLoad()

// Do any additional setup after loading the view, typically from a nib.

}

override func didReceiveMemoryWarning() {

super.didReceiveMemoryWarning()

// Dispose of any resources that can be recreated.

}

}

 

WebView.swift

 

//

//WKWebView.swift

//WKWebView

//

//Created by Tansu Canturk on 30/8/18.

//Copyright © 2018 Subz Designs. All rights reserved.

//

import UIKit

import WebKit

class WebView: UIViewController ,WKNavigationDelegate, WKUIDelegate {

@IBOutlet weak var pageTitle: UILabel!

@IBOutlet weak var webView: WKWebView!

@IBOutlet weak var preloader:

UIActivityIndicatorView!

let url = URL(string: “https://subzdesigns.com/blog/WKWebView-tel-mailto-target-blank-check-connection”)

override var preferredStatusBarStyle: UIStatusBarStyle {

return .lightContent

}

override func viewDidLoad() {

super.viewDidLoad()

self.preloader.transform = CGAffineTransform(scaleX: 2, y: 2)

pageTitle.text = “Loading”

webView.navigationDelegate = self

webView.uiDelegate = self

let htmlpath = Bundle.main.path(forResource: “index”, ofType: “html”)

webView.scrollView.bounces = false

let request = URLRequest(url: url!)

webView.load(request)

self.webView.addObserver(self, forKeyPath: #keyPath(WKWebView.isLoading), options: .new, context: nil)

}

override func viewDidAppear(_ animated: Bool) {

if CheckInternet.Connection(){

//Connected

}else{

self.Alert(Title: “No connection”, Message: “Your Device is not connected with internet”)

}

}

func Alert (Title: String, Message: String){

let alert = UIAlertController(title: Title, message: Message, preferredStyle: UIAlertControllerStyle.alert)

alert.addAction(UIAlertAction(title: “Retry”, style: UIAlertActionStyle.default, handler: retrybtn))

self.present(alert, animated: true, completion: nil)

}

func retrybtn(alert: UIAlertAction!) {

if CheckInternet.Connection(){

//Connected

let request = URLRequest(url: url!)

webView.load(request)

self.webView.addObserver(self, forKeyPath: #keyPath(WKWebView.isLoading), options: .new, context: nil)

pageTitle.text = “Loading”

}

else{

self.Alert(Title: “No connection”, Message: “Your Device is not connected with internet”)

}

}

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)

}

}

@IBAction func backButton(_ sender: Any) {

if(webView.canGoBack) {

webView.goBack()

}

if !webView.canGoBack {

self.Alert(Title: “Notification”, Message: “Can’t go back further”)

}

}

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {

if keyPath == “loading” {

if self.webView.isLoading {

self.preloader.startAnimating()

self.preloader.isHidden = false

pageTitle.text = “Loading”

self.pageTitle.alpha = 0.0

UIView.animate(withDuration: 1, animations: {

self.pageTitle.alpha = 1.0

})

} else {

self.preloader.stopAnimating()

self.preloader.isHidden = true

pageTitle.text = “Subz Designs”

self.pageTitle.alpha = 0.0

UIView.animate(withDuration: 1, animations: {

self.pageTitle.alpha = 1.0

})

}

}

}

override var prefersStatusBarHidden: Bool {

return false

}

}

 

CheckInternet.swift

//

//CheckInternet.swift

//WKWebView

//

//Created by Tansu Canturk on 30/8/18.

//Copyright © 2018 Subz Designs. All rights reserved.

//

import SystemConfiguration

public class CheckInternet{

class func Connection() -> Bool{

var zeroAddress = sockaddr_in(sin_len: 0, sin_family: 0, sin_port: 0, sin_addr: in_addr(s_addr: 0), sin_zero: (0, 0, 0, 0, 0, 0, 0, 0))

zeroAddress.sin_len = UInt8(MemoryLayout.size(ofValue: zeroAddress))

zeroAddress.sin_family = sa_family_t(AF_INET)

let defaultRouteReachability = withUnsafePointer(to: &zeroAddress) {

$0.withMemoryRebound(to: sockaddr.self, capacity: 1) {zeroSockAddress in

SCNetworkReachabilityCreateWithAddress(nil, zeroSockAddress)

}

}

var flags: SCNetworkReachabilityFlags = SCNetworkReachabilityFlags(rawValue: 0)

if SCNetworkReachabilityGetFlags(defaultRouteReachability!, &flags) == false {

return false

}

// Working for Cellular and WIFI

let isReachable = (flags.rawValue & UInt32(kSCNetworkFlagsReachable)) != 0

let needsConnection = (flags.rawValue & UInt32(kSCNetworkFlagsConnectionRequired)) != 0

let ret = (isReachable && !needsConnection)

return ret

}

}

 

Screenshots:

 

Source code:

Click to download