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 {