Executing JavaScript from Objective-C in an iOS App

The other day, I found the need to execute some JavaScript from a native iOS application.  After doing a little research, I discovered that the UIWebView has a stringByEvaluatingJavaScriptFromString method.  So I decided to create a quick little proof-of-concept to see how to invoke some JavaScript using this. I am not going to walk through all the details of creating a project, etc. and will cut right to the important aspects of making the JavaScript call from the objective-c code.

We are going to need a JavaScript function to call and a UIWebView to evaluate the JavaScript. It would be nice if the JavaScript function took a parameter as well, so we could also prove out the passing of values.  Here is the JavaScript function that I will use:

var area = function(diameter) {
     var radius = diameter/2,
     area = Math.PI * radius * radius;
     return Math.round(area*100)/100;
};

Next we need to load this JavaScript in a UIWebView to allow for the call to stringByEvaluatingJavaScriptFromString. This can be done several ways. One option is to embed JavaScript in a dummy html file and load that into the UIWebView. You could also load an externalized JS file into the dummy html file. I chose to load some inline html into the UIWebView that included a reference to the externalized JS file. This way I don’t need any extraneous files hanging around. Also, I wanted the JS to live in its own file and act as a library I could use in other (non-objective-c) applications, so I placed it in the calc.js file. Here is the code to load the JS file into the UIWebView:

[webView loadHTMLString:@"<script src=\"calc.js\"></script>" 
              baseURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] resourcePath]]];

Here is the code to make the JS call:

NSString *function = [[NSString alloc] initWithFormat: @"area(%i)", diameter];
NSString *result = [webView stringByEvaluatingJavaScriptFromString:function];

Now, there is one important safety tip to make this actually work: The UIWebView must actually be loaded a view. It doesn’t have to be visible, but in order for the WebKit engine to execute the JS, it must be on a view.

Also, when you perform a build, you will get the following warning:

no rule to process file ‘$(PROJECT_DIR)/Classes/calc.js’ of type sourcecode.javascript for architecture i386

This can be eliminated by moving the calc.js file from the Compile Sources Task to the Copy Bundle Resources task within your project target. It should look something like the image below.

Project Pane - Target

That should do it. Once all these pieces are in place, you will have objective-c executing JavaScript.

The source code can be found on github here.

Please forgive the UI (and the lack of memory mgmt), as I just threw this together :)

About these ads

8 comments

  1. I started research on Core Plot and was disappointed. Two hours of research later, my journey has ended satisfactorily here. Great tutorial!

  2. Do you mind if I quote a couple of your posts as long as I provide credit and sources back to your
    site? My blog is in the exact same niche as yours and my users
    would certainly benefit from a lot of the information you present here.
    Please let me know if this ok with you. Thanks a lot!

  3. Thank you very much for this post Steven !

    I’ve run into a bit of a problem. Everything works fine if there is only function in the JS file.
    If I write another function and try to call it at some other time, it just wont happen.

    I even tried it by maintaining different JS files for each of the functions. NO Luck :(

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s