How to call javascript function from .js file in swift

rajes picture rajes · Dec 27, 2016 · Viewed 10.4k times · Source

I tried to call a Javascript function from swift using below code but can't access the Javascript function

This is how I create the Javascript context object:

lazy var context: JSContext? = {
        let context = JSContext()

        guard let
            JSPath = Bundle.main.path(forResource: "IAV", ofType: "html")
            else {
                print("Unable to read resource files.")
                return nil
        }


        do {
            let iav = try String(contentsOfFile: JSPath, encoding: String.Encoding.utf8)
            _ = context?.evaluateScript(iav)
        } catch (let error) {
            print("Error while processing script file: \(error)")
        }

        return context
    }()

//Set value to js

func setToken(Token:String)
    {
        let jsmethod = context?.objectForKeyedSubscript("setIAVToken")
        let passParameter = jsmethod?.call(withArguments: [Token])
    }

The content of html file is



sample IAV form

</head>  


<body > <header> </header> <main>
<h1>Registration Form</h1>  
<form id="myform" method="post">  
 <div id="mainContainer">   <input type="button" id="start" value="Add Bank"> </div>  

var value="dhjhsd";

var setIAVToken = function(token) {
value= token;
}


$('#start').click(function() {
var iavToken = value;
alert(iavToken)
dwolla.configure('uat');
dwolla.iav.start('iavContainer', iavToken, function(err, res) {
console.log('Error: ' + JSON.stringify(err) + ' -- Response: ' + JSON.stringify(res));
});
}); </script> </html>

Answer

denis_lor picture denis_lor · Jan 25, 2019

You should probably use WKWebView (which is the new way to load web content in a webview in iOS since it uses WebKit and has lots of improvements like better memory allocation than it does WebView).

In a swift file WebviewBridging.swift in iOS you could have something like

import UIKit
import WebKit

class WebviewBridging: UIViewController, WKNavigationDelegate {

    var webView: WKWebView?

    override func viewDidLoad() {
        super.viewDidLoad()

        // Create a WKWebView instance
        webView = WKWebView (frame: self.view.frame, configuration: webConfig)
        view.addSubview(webView!)
    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)

        let url = Bundle.main.url(forResource: "index", withExtension: "html")!
        webView!.loadFileURL(url, allowingReadAccessTo: url)
    }

    func callJSFunctionFromSwift(){
        webView!.evaluateJavaScript("changeBackgroundColor('red')", completionHandler: nil)
    }
}

In an index.html file on your iOS project folder you could have something like:

<html>
    <head>
    </head>
    <body>
    <script>
    function changeBackgroundColor(colorText) {
        document.body.style.background = colorText;
    }
    </script>
    </body>
</html> 

Whenever you will call callJSFunctionFromSwift() in swift it will communicate with the WKWebView through XPC communication and evaluate your javascript code that will trigger the javascript function in index.html.