I was able to get this to work by using a solution from the linked question and little bit of a hack to determine when to reload the web view with the updated URL.
Here is a little test code that can be copied into an iOS Swift Playground.
import UIKit
import WebKit
class WebVC: UIViewController, WKNavigationDelegate {
var webView: WKWebView!
var pending = false
override func viewDidLoad() {
super.viewDidLoad()
webView = WKWebView()
webView.navigationDelegate = self
webView.addObserver(self, forKeyPath: "URL", options: .new, context: nil)
view.addSubview(webView)
webView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
webView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor),
webView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor),
webView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
webView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor),
])
}
// Code from the linked answer
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey: Any]?, context: UnsafeMutableRawPointer?) {
if object as AnyObject? === webView && keyPath == "URL" {
print(webView.url)
if let url = webView.url, pending {
// Probably need to add a sanity check to avoid a reload loop.
// Not sure if that can happen in some corner case or not.
let req = URLRequest(url: url)
webView.load(req)
}
}
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
let req = URLRequest(url: URL(string: "https://www.lefrecce.it/Channels.Website.WEB/#/white-label/MINISITI/?minisitiCallBackId=54276&isRoundTrip=false&lang=en&departureStation=Salerno&arrivalStation=Caserta")!)
webView.load(req)
}
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, preferences: WKWebpagePreferences) async -> (WKNavigationActionPolicy, WKWebpagePreferences) {
print("decidePolicyFor action, prefs: \(preferences)")
pending = true
return (.allow, preferences)
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
print("didFinish \(navigation)")
pending = false
}
func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
print("Error: \(error)")
}
func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) {
print("Provisional error: \(error)")
}
}
PlaygroundPage.current.liveView = WebVC()
The whole pending
flag is a first attempt to a solution. It's likely a little fragile but it works in this case. There might be corner cases where it ends up causing a loop of reloads so further testing is needed to be sure.
Code also needs to be added to remove the observer from webView
. Probably in a deinit
for the view controller.