Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

using KVO to observe WKWebView's URL property not work in iOS 10

I use WKWebView to load my webpage. When user click a button in webpage, my webpage will open a custom schema URL (e.g. asfle://download?media_id=1). And I use KVO to observe WKWebView's URL property to get the URL. It works well in iOS 9, but it doesn't work in iOS 10. I can't get the url. I use Xcode 8, swift 2.3.

override func viewDidLoad() {
        super.viewDidLoad()

        webView.addObserver(self, forKeyPath: "URL", options: .New, context: nil)
    }

override func observeValueForKeyPath(keyPath: String?,
                                  ofObject object: AnyObject?,
                                           change: [String : AnyObject]?,
                                                  context: UnsafeMutablePointer<Void>)
    {
        print("url:\(webView.URL)")
    }

In iOS 9, it can print url. But in iOS 10 only the website's url get printed, when user touch the button in webpage, nothing get printed.

like image 448
Han Pengbo Avatar asked Nov 02 '16 02:11

Han Pengbo


3 Answers

You can still observe WKWebView's url property, just be sure to hold a strong reference to the returned observation:

class ViewController: UIViewController {
    var webView: WKWebView!
    var urlObservation: NSKeyValueObservation?

    override func viewDidLoad() {
        super.viewDidLoad()

        // ...Initialize web view.
        webView = WKWebView(frame: view.bounds, configuration: WKWebViewConfiguration())
        webView.autoresizingMask = [.flexibleHeight, .flexibleWidth]
        view.addSubview(webView)

        // Add observation.
        urlObservation = webView.observe(\.url, changeHandler: { (webView, change) in
            NSLog("Web view URL changed to \(webView.url?.absoluteString ?? "Empty")")
        })
    }
}

Also, don't forget to capture self as weak in observation closure if you plan to use it there, as otherwise you will get a retain cycle.

like image 177
Alex Staravoitau Avatar answered Nov 14 '22 22:11

Alex Staravoitau


I found the solution. Instead of using KVO, use delegate to detect opening URL.

override func viewDidLoad() {
        super.viewDidLoad()

        webView.navigationDelegate = self
    }

func webView(webView: WKWebView, decidePolicyForNavigationAction navigationAction: WKNavigationAction, decisionHandler: (WKNavigationActionPolicy) -> Void) {
    print("url:\(navigationAction.request.URL)")
    decisionHandler(.Allow)
    }
like image 36
Han Pengbo Avatar answered Nov 14 '22 23:11

Han Pengbo


I found the optional solution.I have get same problem and change this line

        webview.addObserver(self, forKeyPath: #keyPath(WKWebView.estimatedProgress), options:.new, context: nil)
like image 33
Ugur Atci Avatar answered Nov 15 '22 00:11

Ugur Atci