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
Swift 3 Nscache Generic Parameter 'Keytype' Could Not Be Inferred
-[Uithreadsafenode Canperformaction:Withsender:]: Unrecognized Selector Sent to Instance
Dismiss Keyboard with Swipe Gesture
Get Index of Object from Array of Dictionary with Key Value
Swift Get Specific Value from Firebase Database
iOS - Send Image to Instagram - Documentinteraction
Use More Than One Firebase Database in Single App - Swift
How to Add a Ibaction to a Button Programmatically in Swift 4
iOS Swift Connect Wifi Programmatically and Distinguish Between Bad Password and No Wifi in Range
How to Get the Nondecoded Attributes from a Decoder Container in Swift 4
Change Push Notification Sound File, Only Works After iOS Reboot
Swift, Parse.Com: How to Pass Data from Query
Recognizing Touch Events Only Inside the Masked View
How to Handle Oauth-Style Log Ins with Imessage Apps in iOS 10, Xcode 8
@Ibdesignable - View Not Rendering as Expected
Changing Font Size in a Label for Only iPhone 4S, Is This Possible