45

i try to get a function called after my Content inside WKWebView is fully loaded. I found the "didFinishNavigation" function at the Apple Swift WKNavigation Documentation.

func webView(webView: WKWebView!, didFinishNavigation navigation: WKNavigation!) {
    println("WebView content loaded.")
}

But the function never get called.

import UIKit
import WebKit

class ViewController: UIViewController WKNavigationDelegate {

   override func loadView() {
       super.loadView()

       self.webView = WKWebView(frame:self.containerView.frame, configuration: WKWebViewConfiguration())
       self.containerView.addSubview(webView!)
       self.containerView.clipsToBounds = true

   }

   override func viewDidLoad() {
       super.viewDidLoad()

       var url = NSURL(string:"http://google.com/")
       var req = NSURLRequest(URL:url)
       self.webView!.loadRequest(req)
   }

   func webView(webView: WKWebView!, didFinishNavigation navigation: WKNavigation!) {
       println("WebView content loaded.")
   }

}
Darx
  • 1,516
  • 2
  • 13
  • 15

2 Answers2

61

You are not setting the navigationDelegate. Set it and it should be fine.

class ViewController: UIViewController, WKNavigationDelegate {


  override func viewDidLoad() {
    super.viewDidLoad()

    let noLayoutFormatOptions = NSLayoutFormatOptions(rawValue: 0)

    let webView = WKWebView(frame: CGRectZero, configuration: WKWebViewConfiguration())
    webView.setTranslatesAutoresizingMaskIntoConstraints(false)
    webView.navigationDelegate = self
    view.addSubview(webView)

    view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[webView]|", options: noLayoutFormatOptions, metrics: nil, views: ["webView": webView]))

    view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[webView]|", options: noLayoutFormatOptions, metrics: nil, views: ["webView": webView]))

    let url = NSURL(string: "http://google.com")
    let request = NSURLRequest(URL: url)
    webView.loadRequest(request)
  }

  func webView(webView: WKWebView!, didFinishNavigation navigation: WKNavigation!) {
    print("Finished navigating to url \(webView.url)");
  }

}

And here is a bit better version with Swift 3.

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let configuration = WKWebViewConfiguration()
        let webView = WKWebView(frame: .zero, configuration: configuration)
        webView.translatesAutoresizingMaskIntoConstraints = false
        webView.navigationDelegate = self
        view.addSubview(webView)

        [webView.topAnchor.constraint(equalTo: view.topAnchor),
         webView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
         webView.leftAnchor.constraint(equalTo: view.leftAnchor),
         webView.rightAnchor.constraint(equalTo: view.rightAnchor)].forEach  { anchor in
            anchor.isActive = true
        }

        if let url = URL(string: "https://google.com/search?q=westworld") {
            webView.load(URLRequest(url: url))
        }
    }

}

  extension ViewController: WKNavigationDelegate {

    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        print("Finished navigating to url \(webView.url)")
    }

}
Carmen
  • 6,177
  • 1
  • 35
  • 40
Sandeep
  • 20,908
  • 7
  • 66
  • 106
  • get an error in the handler `WKWebView` has no member of `request`, how do you know to which request the navigation belongs? – János Sep 27 '15 at 06:09
  • allZeros is invalid now. It used to be the way to assign empty value to enum in earlier versions of Swift. I have edited the answer now. Thanks for noticing that :) – Sandeep Oct 13 '15 at 19:26
  • 1
    You have to add configuration.preferences.javaScriptEnabled = true; to your configuration, otherwise it won't work. – applecrusher Oct 16 '16 at 15:56
  • @applecrusher I dont think javascript need to be enabled for navigation delegate to work. Do you have proper project setup where you can show me that javascriptEnabled is true to be able to have navigation delegate triggered. – Sandeep Oct 16 '16 at 18:13
  • @Sandeep. You are right you don't need that. I made a mistake. I meant to say you need javaScriptCanOpenWindowsAutomatically = true (at least in Xcode 8 for Swift 3) – applecrusher Oct 16 '16 at 18:25
  • @Sandeep You are right. I have like 3 stackoverflow tabs up right now and I think I was commenting on the wrong question. It is only needed if you are using alerts and confirms inside the native app that you need to set this up. – applecrusher Oct 16 '16 at 18:28
  • Can anyone explain why navigation delegates are not working fine with "flipkart.com" – krishan kumar Sep 17 '19 at 06:52
0

I made a simple mistake for not adding a subview to my View

view.addSubview(webView)

I have created a webView programmatically, here is the complete code

1.. import WebKit

2.. func viewDidLoad()

let request = URLRequest(url: url)
let webView = WKWebView(frame: view.frame)
view.addSubview(webView)
webView.navigationDelegate = self
webView.load(request)

3.. Implement extension for delegate methods

  // MARK: WKWebView
extension ViewController: WKNavigationDelegate {
    
    func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
        print("Start Request")
    }
    
    func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
        print("Failed Request")
    }
    
    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        print("Finished Request")
    }
Ashvin
  • 8,227
  • 3
  • 36
  • 53