首页 > 解决方案 > SwiftUI WKWebView 检测 url 变化

问题描述

我是一个快速的学习者。我使用 SwiftUI 这是一个结构,我必须实现一个 WKWebView ,其中一个 url 是动态变化的。我必须捕捉这些不断变化的网址,但我尝试过的解决方案不起作用。

例如:https ://stackoverflow.com/a/48273950/10088243 我尝试了这个代码块,但它不起作用,它给了我一些编译器错误:

import SwiftUI
import WebKit

struct ContentView: UIViewRepresentable, WKNavigationDelegate {

    let request = URLRequest(url: URL(string: "https://apple.com")!)

    func makeUIView(context: Context) -> WKWebView  {
    let preferences = WKPreferences()
    preferences.javaScriptEnabled = true
    preferences.javaScriptCanOpenWindowsAutomatically = true

    let configuration = WKWebViewConfiguration()
    configuration.preferences = preferences
    let webView = WKWebView(frame: .zero, configuration: configuration)
    webView.allowsBackForwardNavigationGestures = true


    return webView
}

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { 
 // 'override' can only be specified on class membe
  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)
    }
  }
}

func updateUIView(_ uiView: WKWebView, context: Context) {
    uiView.load(request)
}

func webViewDidFinishLoad(webView : WKWebView) {
    print("Loaded: \(String(describing: webView.url))")
}

func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
    print("Loaded: \(String(describing: webView.url))")
    //progressView.isHidden = true
}

func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
    //progressView.isHidden = false
    print("Loaded: \(String(describing: webView.url))")
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

我在 struct ContentView 行有一个非类类型“ContentView”不能符合类协议“NSObjectProtocol”错误...

标签: iosswiftwkwebviewswift5

解决方案


您可以简单地创建一个名为“WebViewModel”的 webview 的 ObservableObject 模型类,例如

class WebViewModel: ObservableObject {
    @Published var link: String
    @Published var didFinishLoading: Bool = false

    init (link: String) {
        self.link = link
    }
} 

并且还进口

import WebKit
import Combine

然后复制此代码片段

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")!))
    }
}

在你看来

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 
                }
        }
   }}

因此,您可以通过这种方式获得其他代表的响应。


推荐阅读