Using JavaScript From Objective-C

The web scripting capabilities of the WebKit permit you to access JavaScript attributes and call JavaScript functions from your Cocoa Objective-C applications. Refer to WebKit DOM Programming Topics if you want to access the Objective-C API from JavaScript.

JavaScript objects are represented by instances of WebScriptObject in Objective-C. The API uses instances of WebScriptObject to wrap script objects passed from the scripting environment to Objective-C. You can use the methods of this class to call JavaScript functions and get/set properties of the JavaScript environment.

You should not create WebScriptObject instances explicitly. Rather, use the windowScriptObject method from WebView to gain access to the scripting environment.

Method parameters must be objects or basic data types like int and float. Objective-C objects will be converted to their JavaScript equivalents by the WebKit:

Let’s look at a couple of examples. You may want to get the URL of the current WebView from JavaScript, rather than accessing the URL from the data source of your WebView’s WebFrame. You can do this with just a few lines of code:

id win = [webView windowScriptObject];
id location = [win valueForKey:@"location"];
NSString *href = [location valueForKey:@"href"];

JavaScript makes it easy to access the attributes of a web page’s window. The WebKit makes it easy to get that information from JavaScript and pass it to Objective-C. Properties, such as location and href, are only available from the script object if the class overrides isKeyExcludedFromWebScript() to return NO for the given properties. The same is true for any selectors. But remember, a key feature of the web scripting system in the WebKit is the ability to call JavaScript functions. One of JavaScript’s built-in functions, location.href, returns the URL of the window in one call. With this in mind, you can slim your three-line URL accessor in the example above down to one simple line:

NSString *href = [[webView windowScriptObject] evaluateWebScript:@"location.href"];

You can also call JavaScript functions with arguments. Assume that you have written a JavaScript function which looks like this:

function addImage(image, width, height) { ... }

Its purpose is to add an image to a web page. It is called with three arguments: image, the URL of the image; width, the screen width of the image; and height, the screen height of the image. You can call this method one of two ways from Objective-C. The first creates the array of arguments prior to using the WebScriptObject bridge:

id win = [webView windowScriptObject];
 
NSArray *args = [NSArray arrayWithObjects:
                    @"sample_graphic.jpg",
                    [NSNumber numberWithInt:320],
                    [NSNumber numberWithInt:240],
                    nil];
 
[win callWebScriptMethod:@"addImage"
            withArguments:args];

The second version sends the arguments right to JavaScript:

[win evaluateWebScript:
    @"addImage(’sample_graphic.jpg’, ‘320’, ‘240’)"];

For more information on using the WebScriptObject to open JavaScript to Objective-C, read the WebKit Objective-C Framework Reference.