3

I need to pass javascript variable to iOS UIWebView, i did the same very easily with Android, but couldnt do here.

What i need is i will click on a link in webview and that link will in-turn call this JS function buttonClickPAss with some parameters, and i want what all parameters i passed in the webside to the native swift code. Not just to call that JS function and return its value in swift.

I will add the entire html code below

<html>
<head>
     <script type="text/javascript">
            function buttonClickPAss(a,b,c)
            {
              //  console.log(action);

                return a;// return what i passed to the function that is valueA
            }
            </script>
</head>
<body>
    <b><a  href='#' onclick="buttonClickPAss('valueA','valueB','valueC');"> Click here from webview</a></b>
</body>
</html>

this 'valueA','valueB' and 'valueC' are populated when the html page is loaded i need those values in my swift code

I will then load the above html page in webview and will click the link from the webview so that the JS function is called, Because my values are getting populated in the webpage.

this is the tutorial i tried in android

https://capdroidandroid.wordpress.com/2015/07/03/how-send-data-from-javascript-to-native-android-app/

but when i searched for the same in ios i found this tutorial

<script type="text/javascript">
            function buttonClickPAss()
            {
              //  console.log(action);

                return 'hi from js';
            }
            </script>

the above is my js code

in native swift i gave this code after loading url

 func webView(_ webView: UIWebView, shouldStartLoadWithRequest request: URLRequest, navigationType: UIWebViewNavigationType) -> Bool {

        let url = request.url!
        let result =  webView.stringByEvaluatingJavaScript(from: "buttonClickPAss()")
        print("Result = ",result!)

return true
}

the above code is working fine, when i clicked on the link which triggers this js function i got the log in my xcode as 'hi from js'

but i need to pass value to the function buttonClickPAss so i changed the above codes to this

in JS

<script type="text/javascript">
            function buttonClickPAss(a,b,c)
            {
              //  console.log(action);

                return a;// return what i passed to the function
            }
            </script>

and in swift side i changed the above swift code to this

 func webView(_ webView: UIWebView, shouldStartLoadWithRequest request: URLRequest, navigationType: UIWebViewNavigationType) -> Bool {

        let url = request.url!
        let result =  webView.stringByEvaluatingJavaScript(from: "buttonClickPAss(a,b,c)")
        print("Result = ",result!)

return true
}

but in here the "Result" is not printing anything,

I searched other tutorials also everywhere it deals with functions with empty parameters, can anybody help me please

one more note, according to the android tutorial above i could pass the js variables separately in three variables to android, is there a similar mechanism in ios swift? worst case i will make it a json string and return it as a single string

Please help

thanks

11
  • try webView.stringByEvaluatingJavaScript(from: "buttonClickPAss('a','b','c')") Commented Jun 1, 2018 at 11:45
  • @SahilManchanda i tried that , but now its returning only 'a', no matter what ever i pass its returning 'a' :( Commented Jun 1, 2018 at 11:59
  • @milsha, from the code you shared for javascript the function is returning "a" Commented Jun 1, 2018 at 12:09
  • @CtrlAltDel no it is supposed to return the value of 'a' right? Commented Jun 1, 2018 at 12:15
  • check my answer Commented Jun 1, 2018 at 12:15

1 Answer 1

2
import UIKit
import WebKit
class ViewController: UIViewController {
    @IBOutlet weak var webView: WKWebView!
    var activityIndicator: UIActivityIndicatorView?
    func setupWebView(){
        webView.navigationDelegate = self
        activityIndicator = UIActivityIndicatorView(activityIndicatorStyle: .gray)
        activityIndicator?.center = self.view.center
        self.view.addSubview(activityIndicator!)
        webView.load(URLRequest(url: URL(string: "YourWebSiteLinkHere")!))
        webView.configuration.userContentController.add(self, name: "myInterface")
        webView.evaluateJavaScript(s, completionHandler: {(string,error) in
            print(error ?? "no error")
        })
        activityIndicator?.startAnimating()
    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
         setupWebView()
    }
}
extension ViewController: WKScriptMessageHandler{
    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
         print("Message received: \(message.name) with body: \(message.body)")
    }
}
extension ViewController: WKNavigationDelegate{
    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        self.activityIndicator?.stopAnimating()
        self.activityIndicator?.removeFromSuperview()
        self.activityIndicator = nil
    }
}

In html Code

<script type="text/javascript">
   function buttonClickPAss(a,b,c){
      //The following line will pass the a to swift 
      window.webkit.messageHandlers.myInterface.postMessage(a)
   }
</script>

In the above I code I registered "myInterface". So that whenever you want to supply data from JavaScript to Swift, you can easily do that. Now in your example, When user clicks on a link the button; buttonClickPAss will be called. now in your buttonClickPAss method the line window.webkit.messageHandlers.myInterface.postMessage(a) will pass the variable data to Swift in func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) method.

I think this should be enough to solve your problem. for more information visit this SO

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

5 Comments

@SahilManchanda Here in my case I have to pass two string parameters from JS to swift. How I can check that specific button tapped? and How can I pass multiple parameter?
@RuchiraMore if look at the swift side didReceive message is called where the message.body is a string, so you could use a delimiter to pass multiple variables from javascript as a string and then split them using the same delimiter on swift side.
@SahilManchanda Thanks Sahil :) This is all about communication from Swift to Javascript. How I can get the data from JS to swift. please check my question here stackoverflow.com/questions/57551779/… There is one server generated Image I want to display on imageview in WKWebview!
@RuchiraMore i replied there. but it seems like that question has nothing to do with communication between swift and javascript
The op is using UIWebView, but your solution references WKWebView. Your solution does not work for UIWebView.

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.