Issue with Observing Wkwebview Url Changes via JavaScript Events

Issue with observing WKWebView URL changes via JavaScript events

Before you go any further, I would strongly recommend that you use the modern Swift method of observing:

var webViewURLObserver: NSKeyValueObservation?

override func viewDidLoad() {
// ...
webViewURLObserver = webview.observe(\.url, options: .new) { webview, change in
print("URL: \(String(describing: change.newValue))")
// The webview parameter is the webview whose url changed
// The change parameter is a NSKeyvalueObservedChange
// n.b.: you don't have to deregister the observation;
// this is handled automatically when webViewURLObserver is dealloced.
}
}

Doing this makes your code much cleaner and easier to reason about while you're debugging the issue.

WKWebView function for detecting if the URL has changed

What do you mean they don't always seem to fire? What kind of elements? They have to in order for the WkWebView to work.

Your first indication that the URL is trying to change is in: decidePolicyForNavigationAction

- (void) webView: (WKWebView *) webView decidePolicyForNavigationAction: (WKNavigationAction *) navigationAction decisionHandler: (void (^)(WKNavigationActionPolicy)) decisionHandler {
NSLog(@"%s", __PRETTY_FUNCTION__);
decisionHandler(WKNavigationActionPolicyAllow); //Always allow
NSURL *u1 = webView.URL;
NSURL *u2 = navigationAction.request.URL; //If changing URLs this one will be different
}

By the time you get to: didStartProvisionalNavigation It has changed.

- (void) webView: (WKWebView *) webView didStartProvisionalNavigation: (WKNavigation *) navigation {
NSLog(@"%s", __PRETTY_FUNCTION__);
NSURL *u1 = webView.URL; //By this time it's changed
}

All you'd have to do is implement these delegate methods (in Swift) and do what you want when you see it change.

How can I detect when url of amp page changed with WKWebview

Same issue. Unfortunately WKWebView only fires its functions when a full page load happens.

So what we have to do instead is use Key Value Observing on the WebKit.url property.

Looks something like this:

import AVFoundation
import UIKit
import WebKit
import MediaPlayer

class ViewController: UIViewController, WKNavigationDelegate {
@IBOutlet weak var webView: WKWebView!

override func viewDidLoad() {
super.viewDidLoad()

webView.navigationDelegate = self

self.webView.addObserver(self, forKeyPath: "URL", options: .new, context: nil)
self.webView.addObserver(self, forKeyPath: "estimatedProgress", options: .new, context: nil)

self.webView.load(URLRequest(url: "https://google.com"))
}

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if keyPath == #keyPath(WKWebView.url) {
print("### URL:", self.webView.url!)
}

if keyPath == #keyPath(WKWebView.estimatedProgress) {
// When page load finishes. Should work on each page reload.
if (self.webView.estimatedProgress == 1) {
print("### EP:", self.webView.estimatedProgress)
}
}
}

Each additional navigation in the wkWebkitView should cause a new combo of "### URL" and "### EP" to fire off.

SwiftUI WKWebView detect url changing

I have found a very good solution to my question. I will post it here. Maybe someone wants to see it and might be useful to them.

observe.observation = uiView.observe(\WKWebView.url, options: .new) { view, change in
if let url = view.url {
// do something with your url
}
}


Related Topics



Leave a reply



Submit