Webkit callAsyncJavaScript not waitng for async await function call in SwiftUI

11 viewsindexeddbiosjavascriptswiftwebkit
0

I am using WebKit in SwiftUI to update my indexedDB, but for some reason, the callAsyncJavaScript function of the webkit module is not waiting for the await response, can someone help? What changes or methods should I implement for the correct functionality of this task? I am new to SwiftUI and want to access the indexedDB.

Here is the sample code for reference.

swiftcode.swift

import SwiftUI
import WebKit

struct IndexedDBView: UIViewRepresentable {
    var jsCode: String

    class Coordinator: NSObject, WKNavigationDelegate {
        var webView: WKWebView?
        var jsCode: String

        init(jsCode: String) {
            self.jsCode = jsCode
        }

        func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
            self.webView = webView
            webView.callAsyncJavaScript(jsCode, in: nil, in: .page) { result in
                switch result {
                case let .failure(error):
                    debugPrint("failure (error)")
                case let .success(result):
                    print(result)
                }
            }
        }
    }

    func makeCoordinator() -> Coordinator {
        return Coordinator(jsCode: jsCode)
    }

    func makeUIView(context: Context) -> WKWebView {
        let webViewConfiguration = WKWebViewConfiguration()
        let webView = WKWebView(frame: .zero, configuration: webViewConfiguration)
        webView.navigationDelegate = context.coordinator
        return webView
    }

    func updateUIView(_ uiView: WKWebView, context: Context) {
        if let htmlPath = Bundle.main.path(forResource: "abcd", ofType: "html") {
            let htmlURL = URL(fileURLWithPath: htmlPath)
            uiView.loadFileURL(htmlURL, allowingReadAccessTo: htmlURL)
        }
    }
}

abcd.html –

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    
    <script src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/crypto-js@3.1.9-1/crypto-js.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/idb@8/build/umd.js"></script>
    <script src="yourScript.js"></script>
    <script src="sample.js"></script>
</head>
<body>
    <div id="updateMe">Initial content</div>
</body>
</html>

sample.js –

const getKeyForEncryptAndDecrypt = (userId) => {
    if (userId) {
        let first = '';
        let second = '';
        for (let index = 0; index < userId.length; index += 2) {
          first += userId[index];
          second = userId[index + 1] + second;
        }
        const key = first + second;
        return key;
      }
      return '';
};

    const handleSetPassAndTicketWithDB = async () => {
        var decryptkey = getKeyForEncryptAndDecrypt('9953425561');
        var myIndexDB = IndexDB(objectStoreKeys.myPassHistory);
        let pass = await myIndexDB.get('twqwa', decryptkey);
        var divElement = document.getElementById('updateMe');
        if (divElement) {
            divElement.innerHTML = 'IndexedDB updated with key: ' + JSON.stringify(pass);
        }
        return pass;
    };

And Here is how I am calling the IndexedDBView in my swiftui code –

IndexedDBView(jsCode: "handleSetPassAndTicketWithDB();")

On the screen, I am getting pass as "undefined".

The IndexDB function contains an object of async-await functions, and is written in yourscript.js file.