Month: January 2011

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 🙂