iOS WKWebView

WKWebView is UIWebView equivalent for iOS8. This is same as Safari Engine. Compare to UIWebView, WKWebView has a lot of features.

Ref

This is great article. nshipster Apple Developer, please check API reference. Apple Developer

Compare to UIWebView

Similar API but a bit different.

  • We can handle web loading behavior using WKNavigationDelegate
  • We can get URL and title using property.(In UIWebView, we have to get both using javascript)
  • Finish delegate(func webView(webView: WKWebView!, didFinishNavigation navigation: WKNavigation!) receives only finish(In UIWebView, receives any other responses)
  • Covers swipe back, forward like Safari
  • Get browsing history

How to use

Add import WebKit

Local HTML and JavaScript

This sample loads local file HTML and executes JavaScript. After loading, insert javascript using API.

Local HTML

<html>
    <head>
    <title>Hello World!</title>
    <script>
        window.onload = function(e){
            var hello = document.getElementById("hello");
            hello.innerHTML = "Hello World!";
        }
    </script>
    </head>
    <body>
        <h1 id="hello">Hello!</h1>
        <input id="user" type="text"/>
    </body>
</html>

Codes

  
mport UIKit
import WebKit

let kHEADERHEIGHT : CGFloat = 44.0
let kFOOTERHEIGHT : CGFloat = 44.0


class ViewController: UIViewController, WKNavigationDelegate {

    var webView : WKWebView = WKWebView()
    var headerView : UIView = UIView()
    var footerView : UIView = UIView()
    var leftArrowButton : UIButton = UIButton.buttonWithType(UIButtonType.Custom) as UIButton
    var rightArrowButton : UIButton = UIButton.buttonWithType(UIButtonType.Custom) as UIButton
    var listButton : UIButton = UIButton.buttonWithType(UIButtonType.Custom) as UIButton
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        webView.allowsBackForwardNavigationGestures = true
        self.view.backgroundColor = UIColor.whiteColor()
        self.headerView.backgroundColor = UIColor.grayColor()
        self.footerView.backgroundColor = UIColor.grayColor()
        
        self.view.addSubview(self.headerView)
        self.view.addSubview(self.webView)
        self.view.addSubview(self.footerView)
        
        self.webView.navigationDelegate = self
        // Local File with simple javacript
        self.webView.loadRequest(NSURLRequest(URL: NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("index", ofType: "html")!)!))
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    override func viewWillLayoutSubviews() {
        let statusBarHeight = UIApplication.sharedApplication().statusBarFrame.height
        self.headerView.frame = CGRectMake(0, statusBarHeight, self.view.frame.size.width, kHEADERHEIGHT)
        self.webView.frame = CGRectMake(0, statusBarHeight+kHEADERHEIGHT, self.view.frame.size.width, self.view.frame.size.height - (statusBarHeight+kHEADERHEIGHT) - kFOOTERHEIGHT)
        self.footerView.frame = CGRectMake(0, self.view.frame.size.height - kFOOTERHEIGHT, self.view.frame.size.width, kFOOTERHEIGHT)
    }
    
    // MARK: WKNavigationDelegate
    func webView(webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
        NSLog("Start")
    }
    
    func webView(webView: WKWebView!, didFailNavigation navigation: WKNavigation!, withError error: NSError!) {
        NSLog("Failed Navigation %@", error.localizedDescription)
    }
    
    func webView(webView: WKWebView!, didFinishNavigation navigation: WKNavigation!) {
        // Finish navigation
        NSLog("Finish Navigation")
        NSLog("Title:%@ URL:%@", webView.title!, webView.URL!)
        
        // Run Javascript(For local)
        webView.evaluateJavaScript("var el=document.getElementById('user');el.style.backgroundColor='yellow';", nil)
    }
}

Results

Local HTML

Web Loading

Add back and forward button and history ref button.

Codes

mport UIKit
import WebKit

let kHEADERHEIGHT : CGFloat = 44.0
let kFOOTERHEIGHT : CGFloat = 44.0

class ViewController: UIViewController, WKNavigationDelegate {

    var webView : WKWebView = WKWebView()
    var headerView : UIView = UIView()
    var footerView : UIView = UIView()
    var leftArrowButton : UIButton = UIButton.buttonWithType(UIButtonType.Custom) as UIButton
    var rightArrowButton : UIButton = UIButton.buttonWithType(UIButtonType.Custom) as UIButton
    var listButton : UIButton = UIButton.buttonWithType(UIButtonType.Custom) as UIButton
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        webView.allowsBackForwardNavigationGestures = true
        self.view.backgroundColor = UIColor.whiteColor()
        self.headerView.backgroundColor = UIColor.grayColor()
        self.footerView.backgroundColor = UIColor.grayColor()
        
        // Image set
        self.leftArrowButton.setImage(UIImage(named: "leftarrow"), forState: .Normal)
        self.leftArrowButton.addTarget(self, action: "back:", forControlEvents: .TouchUpInside)
        self.rightArrowButton.setImage(UIImage(named: "rightarrow"), forState: .Normal)
        self.rightArrowButton.addTarget(self, action: "forward:", forControlEvents: .TouchUpInside)
        
        self.listButton.setTitle("History", forState: .Normal)
        self.listButton.setTitleColor(UIColor.blueColor(), forState: .Normal)
        
        self.listButton.addTarget(self, action: "history:", forControlEvents: .TouchUpInside)
        
        self.view.addSubview(self.headerView)
        self.view.addSubview(self.webView)
        self.view.addSubview(self.footerView)
        self.view.addSubview(self.leftArrowButton)
        self.view.addSubview(self.rightArrowButton)
        self.view.addSubview(self.listButton)
        
        self.webView.navigationDelegate = self
        self.webView .loadRequest(NSURLRequest(URL: NSURL(string: "http://google.com.sg")!))
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    override func viewWillLayoutSubviews() {
        let statusBarHeight = UIApplication.sharedApplication().statusBarFrame.height
        self.headerView.frame = CGRectMake(0, statusBarHeight, self.view.frame.size.width, kHEADERHEIGHT)
        self.webView.frame = CGRectMake(0, statusBarHeight+kHEADERHEIGHT, self.view.frame.size.width, self.view.frame.size.height - (statusBarHeight+kHEADERHEIGHT) - kFOOTERHEIGHT)
        self.footerView.frame = CGRectMake(0, self.view.frame.size.height - kFOOTERHEIGHT, self.view.frame.size.width, kFOOTERHEIGHT)
        
        self.leftArrowButton.frame = CGRectMake(5, self.view.frame.size.height - kFOOTERHEIGHT, kFOOTERHEIGHT, kFOOTERHEIGHT)
        
        self.rightArrowButton.frame = CGRectMake(10 + kFOOTERHEIGHT, self.view.frame.size.height - kFOOTERHEIGHT, kFOOTERHEIGHT, kFOOTERHEIGHT)
        
        self.listButton.frame = CGRectMake(self.view.frame.size.width - 85, self.view.frame.size.height - kFOOTERHEIGHT, 80, kFOOTERHEIGHT)
    }
    
    // MARK: WKNavigationDelegate
    func webView(webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
        NSLog("Start")
    }
    
    func webView(webView: WKWebView!, didFailNavigation navigation: WKNavigation!, withError error: NSError!) {
        NSLog("Failed Navigation %@", error.localizedDescription)
    }
    
    func webView(webView: WKWebView!, didFinishNavigation navigation: WKNavigation!) {
        // Finish navigation
        NSLog("Finish Navigation")
        NSLog("Title:%@ URL:%@", webView.title!, webView.URL!)
    }
    
    // MARK: UI Event
    func history(sender: AnyObject) {
        var list : WKBackForwardList = self.webView.backForwardList
        
        if (list.backItem != nil) {
           NSLog("Back %@", list.backItem!.URL)
        }
        if (list.forwardItem != nil) {
           NSLog("Forward %@", list.forwardItem!.URL)
        }
    }
    
    func back(sender: AnyObject) {
        if (self.webView.canGoBack) {
            self.webView.goBack()
        }
    }
    
    func forward(sender: AnyObject) {
        if (self.webView.canGoForward) {
            self.webView.goForward()
        }
    }
}

Results

Google Load