Ok… we’ve all had that script that looks like it should work but fails miserably and think there’s gotta be a better way. Well there is! I have spent the last several weeks porting all of my Applescript Studio programs to ObjC and Cocoa, and let me say the following: I can’t read my code out loud and hear English anymore, but the code runs MUCH FASTER on my humble little G3 700 iBook (WITH topped up RAM), makes use of more powerfull features of the programming environment, and other things besides. I am not trying to convince you to do the same. This is just where I started the process and You too can take advantage of those powerfull features I mentioned without doing a total rewrite. Here’s how: in the Application Suite of ASK there’s a command call method: here’s what the entry looks like (kinda)
This is what is sometimes referred to as the ObjC bridge. It allows you, the applescripter to call straight to the ObjC runtime, as if you were actually programming in Objc. (Which btw is the native language of Cocoa, the framework upon which all your applescript studio goodness resides). So now, you’ve seen the dictionary entry, but like most dictionary entries, it gives a definition, without any hints on how to use it, or why it might be usefull. lets start by cleaning up that dictionary entry a little and make it a little more encyclopedic:
there are six possible call method syntaxes (syntices? syntaxae? syntaxim?) I mean variants:
call method methodName of theObject
call method methodName of class objcClass
call method methodName of theObject with parameter x
call method methodName of class objcClass with parameter x
call method methodName of theObject with parameters {x,y}
call method methodName of class objcClass with parameters {x,y}
So the first part is figuring out the reciever. If you want to perform an objc call you probably already know what object it is that you want to call. Let’s say you have a webview that you want to display html which you’ve generated in your script, this is an ability outside the realm of applescript studio, but within objc’s reach. Let’s look up the documentation for webkit to see what we can see: file:///Developer/Documentation/Cocoa/Conceptual/DisplayWebContent/index.html Take a look at the page on “Core Web Kit Classes” as we want to know what all the parts are and how they fit together.
A web view is a controller that manages web frame views (that render and display the HTML and web frames, which interface with the various data classes for making the HTML data available to the view. The web view itself has access to all of it’s sub-webframes through it’s “mainFrame”. Let’s see what’s in the WebFrame class (link is in the left hand panel) All apple class documentation follows the layout in this page, so It’s good to know what they look like so you can find the method you want. Go down to the section labelled “Method Types” as this is the quick index of all the methods grouped by type. Under loading content we see “-loadHTMLString:BaseURL:” this looks like what we want. (note on method names: those that start with “-” we call on objects, whereas ones starting with “+” we call on the class. Also note other methods that the class can do are found by following the Inherits From and Implements links near the top of the page. Further, where ever a colon, “:”, appears an argument is expected.) Yup here’s the call we want to make… now how to do it.
The objc call looks like
[[webView mainFrame] loadHTMLString:thePage baseURL:@""];
translating the syntax into applescript we get
tell webView's main frame to load HTML string thePage base URL ""
(that base URL argument is for determining where relative links in the html point to… but you don’t need to worry about that for this tutorial). As there is no applescript studio handlers for WebKit right now, you can’t do that. We have to use the ObjC bridge:
set theWebFrame to call method "mainFrame" of theWebView
call method "loadHTMLString:baseURL:" of theWebFrame with parameters {thePage,""}
Some final notes. Although the objc name has a “-” or “+” at the beginning, don’t include it in the call, also leave out the types and arguments, but the colons are part of the name. An applescript string gets tranformed into an NSString without you having to worry about it. Most things Applescript studio can work with have similar class names in objc, with the parts squished together, using camelback capitalization and starting with “NS”. menu → NSMenu, menu item → NSMenuItem. That should help you look up the documentation. Don’t forget to add the webkit framework to your application if you want to run this.
This has been part one, hoped you like it… tune in next time for part two, where we’ll look at using interface builder for objc through ASSer’s eyes.