SwiftUIでローカルのindex.htmlをWebKitで読んでjavascriptの結果をSwiftコードで読む

ContentView.swiftを変更

import SwiftUI
 
struct ContentView: View {
    var body: some View {
        WebView(url: URL(string: "dummy")!)
    }
}

WebView.swiftを新規作成

import SwiftUI
import WebKit
 
struct WebView: UIViewRepresentable {
    var url: URL
    
    func makeUIView(context: Context) -> WKWebView {
        let webConfig = WKWebViewConfiguration()
        let userController = WKUserContentController()
        userController.add(makeCoordinator(), name: "hoge")
        webConfig.userContentController = userController
        let wkWebView = WKWebView(frame: .zero, configuration: webConfig)
        return wkWebView
    }
    
    func updateUIView(_ uiView: WKWebView, context: Context) {
        // let req = URLRequest(url: url)
        // uiView.load(req)
        guard let path: String = Bundle.main.path(forResource: "index", ofType: "html") else { return }
        let localHTMLUrl = URL(fileURLWithPath: path, isDirectory: false)
        uiView.loadFileURL(localHTMLUrl, allowingReadAccessTo: localHTMLUrl)
    }
/*
     これだと動かない
     func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
        if message.name == "hoge" {
            print("JavaScript is sending a message \(message.body)")
        }
    }
*/
    func makeCoordinator() -> WebView.Coordinator {
        return Coordinator()
    }
    
} // struct
extension WebView {
    class Coordinator: NSObject, WKNavigationDelegate, WKScriptMessageHandler {
       func userContentController(
           _ userContentController: WKUserContentController,
           didReceive message: WKScriptMessage) {
               if message.name == "hoge" {
                 let number = message.body as! Int
                 print("JavaScript is sending a number \(number)")
            }
        }
    }
}
 
struct WebView_Previews: PreviewProvider {
    static var previews: some View {
        WebView(url: URL(string: "dummy")!)
    }
}

index.htmlを新規作成(WebView.swiftと同じフォルダーに置く)

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
  <title></title>
  <meta charset="utf-8" />
</head>
<body>
  <input type="button" value="Exec" onclick="var number = 123; webkit.messageHandlers.hoge.postMessage(number);" /><br />
  <br />
  <div id="output"></div>
</body>
</html>

実行結果(デバッグコンソールに) JavaScript is sending a number 123
なお、ブラウザに出るボタンがめちゃちっちゃい!