I'm trying two-way integration between Swift and Javascript interfacing with SwiftUI.
Here is interfacing WebKit with SwiftUI.
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") shows an error at self with Argument type 'ggWebView' does not conform to expected type 'WKScriptMessageHandler'.
As WKScriptMessageHandler require that object that implements it inherit from NSObject it is better to create a separate class ContentController that will be implementing those protocol, rather than changing the type of 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)
}
}
}
}
You have to confirm ggWebView (BTW this is not the best name for a class because it should start with capital letter) to WKScriptMessageHandler protocol and implement func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) method. You have to change the type of ggWebView from structure to class. I can see that you already add a userContentController(_:didReceive:) method, so you only need to update your class signature to:
class ggWebView: UIViewRepresentable, WKScriptMessageHandler {
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With