SwiftUI WKWebView detect url changing SwiftUI WKWebView detect url changing swift swift

SwiftUI WKWebView detect url changing


You can simply create a ObservableObject model class of webview with the name "WebViewModel" like

class WebViewModel: ObservableObject {    @Published var link: String    @Published var didFinishLoading: Bool = false    init (link: String) {        self.link = link    }} 

and also import

import WebKitimport Combine

and then copy this code snippets

struct SwiftUIWebView: UIViewRepresentable {    @ObservedObject var viewModel: WebViewModel    let webView = WKWebView()    func makeUIView(context: UIViewRepresentableContext<SwiftUIWebView>) -> WKWebView {        self.webView.navigationDelegate = context.coordinator        if let url = URL(string: viewModel.link) {            self.webView.load(URLRequest(url: url))        }        return self.webView    }    func updateUIView(_ uiView: WKWebView, context: UIViewRepresentableContext<SwiftUIWebView>) {        return    }    class Coordinator: NSObject, WKNavigationDelegate {        private var viewModel: WebViewModel        init(_ viewModel: WebViewModel) {            self.viewModel = viewModel        }        func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {            //print("WebView: navigation finished")            self.viewModel.didFinishLoading = true        }    }    func makeCoordinator() -> SwiftUIWebView.Coordinator {        Coordinator(viewModel)    }}struct SwiftUIWebView_Previews: PreviewProvider {    static var previews: some View {                SwiftUIWebView(viewModel: WebViewModel(link: "https://google.com"))        //WebView(request: URLRequest(url: URL(string: "https://www.apple.com")!))    }}

and in you view

struct AnyView: View {    @ObservedObject var model = WebViewModel(link: "https://www.wikipedia.org/")    var body: some View {                    NavigationView {       SwiftUIWebView(viewModel: model)                if model.didFinishLoading {                    //do your stuff                 }        }   }}

so in this way you can get the others delegates response.


you use this to delegates of WKNavigationProtocol to perform(e.g to allow or cancel URL Loading) your action

    func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {    if let host = navigationAction.request.url?.host {        if host.contains("facebook.com") {            decisionHandler(.cancel)            return        }    }    decisionHandler(.allow)}


Use the following delegate function of WKWebView:

func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {  // Suppose you don't want your user to go a restricted site  if let host = navigationAction.request.url?.host {      if host == "restricted.com" {          decisionHandler(.cancel)          return      }  }  decisionHandler(.allow)}

You can read this article from Medium which shows a better way of intercepting every network call or Url changing and obtaining upcoming Url related data. It also shows how to implement WebView in SwiftUI, interfacing with JavaScript functions and loading a local .html file from iOS project