Anton Danilov
Anton Danilov

Reputation: 83

Call swift function from js

Tell me please how should i implement the function in swift so that can be called in js. Now js call function mobile.preScreenerFinished(orderId, account.email, "ACCEPTED"); and it call kotlin function for android.

Here is my code:

import WebKit

protocol PreScreenerUIViewDelegate: class {
    func preScreenerFinished(_ orderId: Int, _ email: String, _ status: String)
}

class PreScreenerUIView: WKWebView, WKScriptMessageHandler {
    
    var delegate: PreScreenerUIViewDelegate!
        
    init(frame: CGRect, orderId: Int) {
        let url = "\(Session.instance.url)/mobile-prescreener"
        let config = WKWebViewConfiguration()
        let contentController = WKUserContentController();
    
        config.userContentController = contentController

        super.init(frame: frame, configuration: config)
    
        contentController.add(self, name: "mobile")
    
        self.load(URLRequest(url: URL(string: url)!))
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
        let dictionary = message.body as? [String: Any]
        guard
            let orderId = dictionary?["orderId"] as? Int,
            let email = dictionary?["email"] as? String,
            let status = dictionary?["status"] as? String
        else { return }
        
        delegate?.preScreenerFinished(orderId, email, status)
    }
}

Upvotes: 1

Views: 512

Answers (1)

gcharita
gcharita

Reputation: 8347

You need to change your Javascript (or inject Javascript code) to call postMessage() function instead. Since you can only pass one parameter you can compose a JSON:

window.webkit.messageHandlers.mobile.postMessage({
    "orderId": orderId,
    "email": account.email,
    "status": "ACCEPTED"
});

That way you can handle body property of WKScriptMessage like a dictionary, in Swift:

func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
    let dictionary = message.body as? [String: Any]
    guard
        let orderId = dictionary?["orderId"] as? Int,
        let email = dictionary?["email"] as? String,
        let status = dictionary?["status"] as? String
    else { return }
    
    delegate?.preScreenerFinished(orderId, email, status)
}

Upvotes: 3

Related Questions