3

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>
2
  • You can also check for raywenderlich.com/124075/javascriptcore-tutorial Commented Dec 27, 2016 at 13:13
  • already checked,there getting error in method let parseFunction = context.objectForKeyedSubscript("parseJson") guard let parsed = parseFunction?.call(withArguments: [response]).toArray() else { print("Unable to parse JSON") return [] } getting print("Unable to parse JSON") message Commented Dec 27, 2016 at 13:20

3 Answers 3

5

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.

Sign up to request clarification or add additional context in comments.

Comments

3

In case of objective c do the following:

  • #import <JavaScriptCore/JavaScriptCore.h> in header file.

  • Next use this code inside viewcontroller.

NSString *jsPath = [[NSBundle mainBundle] pathForResource:@"JSFileName" ofType:@"js"];

NSString *scriptString = [NSString stringWithContentsOfFile:jsPath encoding:NSUTF8StringEncoding error:nil];

JSContext *context = [[JSContext alloc] init];
    context = [[JSContext alloc] init];
    [context evaluateScript:scriptString];
    JSValue *function = context[@"setMessage"];
    JSValue* result = [function callWithArguments:@[@"your custom string"]]; //pass the string whatever you want.
    [result toString]; // This will give the value in string format.

14 Comments

me also do same thing swift :let JSPath = Bundle.main.path(forResource: "jsfile", ofType: "js") let alert = try String(contentsOfFile: JSPath, encoding: String.Encoding.utf8) _ = context?.evaluateScript(alert) let jsmethod = context?.objectForKeyedSubscript("jsfunctionName") let passParameter = jsmethod?.call(withArguments: [message])
@rajes : Then what's the problem? It is the correct way to call a js function from ios.
me show alert(message) inside the setmessage function in js file, but can't show alert while executing
js for UIWebView,executing inside webViewDidStartLoad
load js on web view with dynamic value is my goal its possible?
|
0

Edit the html, use <input type="button" id="start" value="Add Bank" onClick="setMessage()"> instead of <input type="button" id="start" value="Add Bank">

Also add <input type="hidden" id="token" value="Token value"> inside the form to pass the token value.

In the javascript method:

<script>
  function setMessage() {
  var iavToken = document.getElementById("token").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>

Next invoke the javascript function using the following objective c.

NSString * jsCallBack = [NSString stringWithFormat:@"setMessage()"]; 
 [webView stringByEvaluatingJavaScriptFromString:jsCallBack];

P.S: You need to add <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> (or if you have the js file locally add it.) in the html to work with the js.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.