Can a class instance in a View struct interact with the view's State variable?

SwiftUI question: (How) Can the myClass instance in this View interact with a State variable?

Not working:
Code Block
struct MyView: View {
@State private var hello = "world"
let myClass = MyClass()
class MyClass: NSObject, WKScriptMessageHandler {
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
if message.name == "hello"{
hello = message.body
}
}
// ...
}

by the way, I’m adding myClass to a webview’s configuration.userContentController. The userContentController in the class gets called when javascript calls window.webkit.messageHandlers.hello.postMessage("new world")

Thank you kindly
Here's code for my completed use case:

Code Block swift
import SwiftUI
import WebKit
import WebView /* Using Swift Package Dependency: https://github.com/kylehickinson/SwiftUI-WebView */
struct ContentView: View {
@StateObject private var webViewStore: WebViewStore
@State private var hello = "SwiftUI world"
class MyClass: NSObject, WKScriptMessageHandler {
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
if message.name == "hello" {
print(message.body) /* this works */
/* but how do I change ContentView's hello State from here? */
}
}
}
init() {
let userContentController = WKUserContentController()
let configuration = WKWebViewConfiguration()
let userScript = WKUserScript(
source: """
function elementReady(selector) {
return new Promise((resolve, reject) => {
let el = document.querySelector(selector)
if (el) {
resolve(el)
}
new MutationObserver((mutationRecords, observer) => {
Array.from(document.querySelectorAll(selector)).forEach((element) => {
resolve(element)
observer.disconnect()
})
}).observe(document.documentElement, {
childList: true,
subtree: true,
})
})
}
elementReady("h1").then((titleElement) => {
window.webkit.messageHandlers.hello.postMessage(titleElement.textContent)
})
""",
injectionTime: .atDocumentStart,
forMainFrameOnly: false,
in: .defaultClient
)
let myClass = MyClass()
userContentController.add(myClass, contentWorld: .defaultClient, name: "hello")
userContentController.addUserScript(userScript)
configuration.userContentController = userContentController
let webView = WKWebView(frame: .zero, configuration: configuration)
_webViewStore = StateObject(wrappedValue: WebViewStore(webView: webView))
}
var body: some View {
Text("Hello \(hello)")
WebView(webView: webViewStore.webView)
.onAppear {
webViewStore.webView.loadHTMLString("<h1>JS world</h1>", baseURL: nil)
/* I'll be loading any kind of webpage here */
}
Button("load new world") {
/* load new page with h1 tag */
webViewStore.webView.loadHTMLString("<h1>new world</h1>", baseURL: nil)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}


Can a class instance in a View struct interact with the view's State variable?
 
 
Q