swift - 参数类型不符合预期类型 'WKScriptMessageHandler'

标签 swift wkwebview swiftui wkwebviewconfiguration

我正在尝试在 Swift 和 Javascript 之间与 SwiftUI 进行双向集成。
这是 WebKit 与 SwiftUI 的接口(interface)。

import SwiftUI
import WebKit

struct ggWebView : UIViewRepresentable {

    let filePath: String

    func makeUIView(context: Context) -> WKWebView  {
        return WKWebView()
    }

    func updateUIView(_ uiView: WKWebView, context: Context) {
        uiView.configuration.userContentController.add(self, name: "jsHandler")
        let bundleURL = Bundle.main.resourceURL!.absoluteURL
        let html = bundleURL.appendingPathComponent(filePath)
        uiView.loadFileURL(html, allowingReadAccessTo:bundleURL)
    }

    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
        if message.name == "jsHandler"{
            print(message.body)
        }
    }
}

userContentController.add(self, name: "jsHandler")self 处显示错误,参数类型“ggWebView”不符合预期类型“WKScriptMessageHandler'.

最佳答案

由于 WKScriptMessageHandler 要求实现它的对象从 NSObject 继承,因此最好创建一个单独的类 ContentController 来实现这些协议(protocol),而不是更改 GgWebView 的类型。

import SwiftUI
import WebKit

struct GgWebView: UIViewRepresentable {

    let filePath: String
    let contentController = ContentController()

    func makeUIView(context: Context) -> WKWebView  {
        return WKWebView()
    }

    func updateUIView(_ uiView: WKWebView, context: Context) {
        uiView.configuration.userContentController.add(contentController, name: "jsHandler")
        let bundleURL = Bundle.main.resourceURL!.absoluteURL
        let html = bundleURL.appendingPathComponent(filePath)
        uiView.loadFileURL(html, allowingReadAccessTo:bundleURL)
    }

    class ContentController: NSObject, WKScriptMessageHandler {
        func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
            if message.name == "jsHandler"{
                print(message.body)
            }
        }
    }
}
<小时/>

您必须确认ggWebView(顺便说一句,这不是类的最佳名称,因为它应该以大写字母开头)到WKScriptMessageHandler协议(protocol)并实现func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) 方法。您必须将ggWebView的类型从struct更改为class。我可以看到您已经添加了 userContentController(_:didReceive:) 方法,因此您只需将类签名更新为:

class ggWebView: UIViewRepresentable, WKScriptMessageHandler {

关于swift - 参数类型不符合预期类型 'WKScriptMessageHandler',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58878348/

相关文章:

ios - 具有嵌套队列的串行调度队列

ios - Xcode Swift Collection View : How can I add the number of items in section whenever the button is tapped?

swift - a 如何在结构中使用 setter 的值进行操作?

swift - UILabel 不会随计时器更新

core-data - 带有核心数据的SwiftUI在Xcode 12中的模拟器中出现空白屏幕

swiftui - 在 SwiftUI 中向 ScrollView 内的 View 添加拖动手势会阻止滚动

javascript - WKWebView 未从 language.url 获取正确的语言字符串

ios - WKWebview getAllCookies 在 iOS 11.3 中崩溃

ios - 如何在 iOS webview 的多个页面中注入(inject)/评估 JS?

mvvm - SwiftUI 使用高频数据更新 UI