How keep JavaScript data in sync with SwiftUI?

I'm trying to observe an audio element on a webpage. How do I best keep it's "JS" data in sync with SwiftUI?

Here's the start of my view:

Code Block
struct ContentView: View {
    // @State private var webAudioElementFound = false
    @State private var paused = true
    @State private var currentTime = 0.0
    @State private var duration = 0.0
    private let timer = Timer.publish(every: 0.5, on: .main, in: .common).autoconnect()
    @StateObject private var webViewStore: WebViewStore
    private let userContentController = WKUserContentController()
    private let configuration = WKWebViewConfiguration()
    private 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,
              })
            })
          }
          window.webAudioPromise = elementReady("audio").then((webAudioElement) => {
            window.webAudioElement = webAudioElement
          })
        """,
        injectionTime: .atDocumentStart,
        forMainFrameOnly: false,
        in: .defaultClient
    )
    init() {
        userContentController.addUserScript(userScript)
        configuration.userContentController = userContentController
        configuration.mediaTypesRequiringUserActionForPlayback = []
        let webView = WKWebView(frame: .zero, configuration: configuration)
        webView.customUserAgent = "Mozilla"
        _webViewStore = StateObject(wrappedValue: WebViewStore(webView: webView))
    }


the body:

Code Block
            WebView(webView: webViewStore.webView)
                .onReceive(timer, perform: webViewTimer)


and a the webViewTimer method:
Code Block
    func webViewTimer(time: Date) {
        checkPlayback()
        if !webViewStore.isLoading && !paused {
            webViewStore.webView.evaluateJavaScript("[webAudioElement.duration, webAudioElement.currentTime]",
                in: nil, in: .defaultClient,
                completionHandler: { result in
                    switch result {
                    case .success(let value):
                        guard let array = value as? [Double] else { return }
                        duration = array[0]
                        currentTime = array[1]
                    case .failure(let failure):
                        print("timer failure: \(failure.localizedDescription)")
                        break
                    }
                })
        }
    }

As you can see, I'm using Timer, but surely there must be a better way no?
How keep JavaScript data in sync with SwiftUI?
 
 
Q