Configure player

Close

WWDC Index does not host video files

If you have access to video files, you can configure a URL pattern to be used in a video player.

URL pattern

preview

Use any of these variables in your URL pattern, the pattern is stored in your browsers' local storage.

$id
ID of session: wwdc2009-403
$eventId
ID of event: wwdc2009
$eventContentId
ID of session without event part: 403
$eventShortId
Shortened ID of event: wwdc09
$year
Year of session: 2009
$extension
Extension of original filename: m4v
$filenameAlmostEvery
Filename from "(Almost) Every..." gist: [2009] [Session 403] AppleScript...

WWDC09 • Session 403

AppleScript and Cocoa Bridge

Mac • 52:00

AppleScript is now a first-class language for Cocoa development thanks to the updated Cocoa Bridge in Snow Leopard. Discover how the Cocoa Bridge gives AppleScript consistent access to all the Cocoa frameworks, including full support for bindings and connections in Interface Builder. Learn how to transition your applications from AppleScript Studio to this more powerful, efficient architecture.

Speakers: Chris Nebel, Michael Gorbach

Unlisted on Apple Developer site

Downloads from Apple

SD Video (145.4 MB)

Transcript

This transcript has potential transcription errors. We are working on an improved version.

I'm Chris Nebel, your host for this morning. I'll be joined later by Michael Gorbach, who's also on the Automation Team just like me. And so, this is all about writing applications and AppleScript, and if you want to write an application in Mac OS X, you want to be using the Cocoa frameworks. Cocoa is where Apple puts all of their, all of our effort, all of the tools are designed to work well with Cocoa.

Use our stuff and your work will go much easier. Now, Cocoa was originally designed for Objective-C, but that's actually not required. These days, you can use any number of languages thanks to technologies we call Cocoa bridges. The idea is that there is a little bridge piece that sits in between your favorite language and the Cocoa framework and allows them to talk back and forth together. So for instance, we've been shipping bridges for Python and Ruby on the system since Leopard. There are a variety of bridges out there for other languages, JavaScript, there's one for Lisp and so on.

But the one we're interested in today is AppleScript. Oh, and by the way, if I start to sound kind of slowed down a bit, it's not because I'm hung over or anything from last night, which was very good by the way, I'm trying to do what they told me to do in rehearsal so I don't sound quite so much like a hyper-caffeinated squirrel.

Anyway, so, we're going to talk some about what's new in AppleScript, and there are some changes in Snow Leopard, lots of refinements just like the rest of the system, and we'll spend most of the time talking about how to write a Cocoa application using AppleScript. So first up, AppleScript.

For those of you who aren't quite as familiar with AppleScript, AppleScript is the original and in many ways still the premiere in automation language in Mac OS X. It was designed with a very readable English-like syntax, designed to be easy to read and to write, and its big schtick is controlling other applications.

You've actually been seeing AppleScript a fair bit at this show, even if you didn't realize it. Anytime, like during the keynote where they appear to press one button and whole bunch of windows scramble around, that's an AppleScript setting things up for them. AppleScript is also very useful for doing automated testing.

Microsoft uses the AppleScript to do all of their regression testing for Microsoft Office. It's very useful in workflows, a lot of print and publishing houses use AppleScript to drive their whole process. For instance, if you see a real estate catalog or weather map, odds are very, very good that it was produced using AppleScript.

So what's new in Snow Leopard? We've got a bunch of different things. There are some developer improvements, things that are relevant if you are writing an application that uses AppleScript. There are a bunch of language improvements if you're writing something actually in AppleScript. And there are a number of tool improvements as well, better syntax coloring, better logging and multi-threading which actually affects all of those areas. So to show you some of that, I'd like to introduce Michael Gorbach to do the demo.

Thank you.

[ Applause ]

Morning everyone. Thank you for showing up despite the bash. We really appreciate you being here. So we're going to talk about AppleScript, and AppleScript as Chris said, is Apple's automation range. It is an expert at interacting with other applications, and that's going to be our first demo. Here we go. So I'm going to start off a script, and this is Script Editor, which is Apple's main environment for editing for AppleScripts.

It ships on every Mac and you can pull it up on your computer right now if you want. We're going to be interacting with an application called Sketch. Sketch is a demo app that we've been working with for some time. It's designed to demonstrate script ability and drawing perimeters in Cocoa. So one thing I want to point out on this script before I give Sketch a start, is that we've really improved syntax highlighting in Script Editor. We've changed the colors up a bit so that it's much easier to differentiate them from each other.

It's a lot clearer now to see the differences between scripting terminology, user terminology, addition terminology, and so on. Actually, this is a surprisingly big deal, because it makes AppleScript a lot easier to debug and it makes it a lot easier to make sense of what your script is doing and why. So I'm going to start up this script and just started up Sketch, and it's drawing us some circles. I'm going to click on another script.

Start that and the red circles are turning green now, and I'm going to click on one more script and start that, too, and the circles are starting to disappear as you can see. So if you stare at this for a while, there's actually a pattern going on. We have 3 scripts running, yes they're running at the same time, that's multi-threaded AppleScript. I'll give you a second to ponder on that.

[ Applause ]

Just to prove to you that this isn't some kind of a trick, script editor is still responsive; we can start and stop scripts; we can access the logs; Sketch is still responsive; and everything works as expected. So one of these scripts is drawing the red circles, the second is turning them green, and the third is sort of an AppleScript garbage collector. It's aging the circles over a few steps and fading their color and slowly deleting them.

So there are also a few things I want to point out about improvements in the Script Editor app itself. We've really improved the logging quite a bit for scripts. The log is now always on, so you don't have to specifically enable that logging. It's just always there for you so you can debug when you need it. We've added dynamic filterings so that while your script is running you can choose whether you're viewing events, groupwise or both. We can see that the result of the script is now displayed in the log as well as any log statements from your scripting that's running.

And the last thing that I wanted to point out was that we've added a little feature, which is going to be real useful to those of you who are developing Cocoa apps using circularity. There it is. You can see we've got the raw Apple event information coming up.

I'm going to try to zoom on it for you. There you go, come on, come on, come on. There you go.

[ Applause ]

We know how much you are for character codes, so we wanted to show them to you. That's all for Script Editor, and I'll bring Chris back up on stage.

Thank you, Michael. OK, so to recap. AppleScript in Snow Leopard, tool improvements. One thing that Michael kind of skimmed over, but you might have noticed in the message-- in the menu bar is that Script Editor is not called Script Editor anymore. It's been renamed to AppleScript Editor and moved to the utilities folder to streamline the applications folder a bit.

It is now fully multi-threaded, taking advantage of multi-threaded AppleScripts so you can run a number of scripts at the same time and they all interact smoothly together. The event logging has been improved so, in particular, you don't have to decide ahead of time what you want to look at in the log like you did before. You can just run the script and then switch the various bits on and off as you need them.

And finally, finer grained syntax coloring, so all the different parts of speech have their own independent styles, and you can also specifically distinguish application terms from scripting edition terms, which is really helpful for when you're debugging scripts and want to make sure the right events are going to the right places. In the language, lots of refinements, a lot of bug fixes, a lot of old bug fixes. The, this is-- actually one of the oldest bugs fixed in Snow Leopard is the first one.

So do you remember, who here uses text item delimiters? In AppleScript? Yeah. A bunch of people? OK. So do you remember in the documentation there's this little note about how text item delimiters is actually a list, but only the first one actually matters? Yeah, we can remove that qualifier now.

They all matter. So you know, finally implemented that after...

[ Applause ]

...some number of years I'm not going to admit to. There have been a number of performance improvements. We've improved the start-up time of the interpreter itself; a number of individual operations have been improved. We do not-- AppleScript does not depend on the Windows server anymore.

AppleScript itself can now be run completely headlessly, which is a big deal for production servers.

[ Applause ]

Thank you. Should point out that-- things that-- this is just AppleScript itself. Things your script uses might still depend on the Window server, so maybe some kinks to work out there, but at least all our stuff does not depend on the Window server.

We've improved Unicode and Local supports more, so we now work better with Unicode-only Locals and custom date formatting, things like that. And there's a complete list in the AppleScript release notes. Those are live now on the Snow Leopard reference library-- library which you can get to through your ABC account. Developer improvements-- and some of these actually play both ways, but they're-whether you're writing an app that uses AppleScript, or you're using AppleScript itself. First thing is, it's all 64-bit.

So if you've got a 64-bit app, you can use AppleScript. It's, the language is 64-bit, all of the scripting additions are 64-bit, all of the applications that we provide are 64-bit, all stack. The other thing is that-- the big thing is that it's all thread-safe now. AppleScript now works on background threads, it works on multiple threads simultaneously, and it takes care of its own logging.

So all that-- all that GCD stuff that you've been hearing about all week, you can use that with AppleScript. Now you can throw an AppleScript onto, onto a background work queue and it's fine. What this means is that as scripters, you get more responsive applications. Like Script Editor, like AppleScript Editor, you were seeing before and as an after developer it means that if you want to run a script, like Mail, it has its Mail rules. If you have an app that can somehow attach an Outlook script action to something, you can run that script on a background thread and keep your main UI thread responsive. So your users get a better experience.

But, see we have at least some enthusiasts in the audience. So scripting additions may or may not be thread-safe. To the extent that we-- that they can be made, made thread-safe, we have, but some of them do inherently main-thread-only things, in particular, user interface, to display dialog. It's arranged so that such additions like that will execute on the main thread, and the system takes care of itself. The third party additions will need to flag themselves as to whether or not they're thread-safe. By default, it's assumed that they're not thread-safe. So if you're having a scripting addition which actually is thread-safe, then it needs to say so in its Info.plist.

There are details on how to do this in Tech Note 1164, which is all about how to write a scripting addition. And a third kind of big thing, is an improved security model for scripting additions. This actually came about in-- it actually started to kick in in 10.5.4. The-- because you tell scripting to tell some other application to do scripting addition, that scripting addition actually loads, and it executes in that other process, so this means you're doing a form of code injections which opens up some vulnerabilities, so we've been plugging those.

And the, the big change in Snow Leopard was simply to make the-- like I said it was actually added in 10.5.4-- what we've done is made the scheme of it more general and easier for developers to work with. We went to some pains to make sure that it was as compatible as possible. So 99% of you won't need it, won't actually need to change your scripts at all. Ideally, you do want to move scripting addition calls outside of tell blocks or use tellMe to.

That way it goes to your application not what-- not whoever else you're telling like Finder or what not. You can see the AppleScript notes for details. Like I said, this is not essential because we did try to be compatible, but it's sort of good practice to do this. A lot of developers have been going on about this for years.

That's like, oh, but you know, move your addition calls out of tell blocks, they don't need to be in there. Well, now it's just a little more important. If you are writing a scripting addition, there is a new bit of information that you can add, you should add to your scripting addition which is contact, which is basically where does the scripting addition actually need to run.

Does it really need to run that other process or can it really just be run anywhere? It can be run locally if it has to. Try to make this as general as possible. Again, do see Tech Note 1164. If you've got a scripting addition that is misbehaving and, or not behaving as well as you'd like, and you would like the developer to fix it, this is the thing to bug them about.

So summing up on AppleScript, lots and lots of refinements, various good bits, few new smallish, can't even say the word features, sorry. Improved tools, AppleScript editor has a number of substantial improvements. In general, AppleScript is now, oh, what I like to call future compatible. So 64-bit machines, it works nicely there. It's all thread-safe so it works with all the multi-core, or multi-threading stuff that's been introduced.

So that's AppleScript. Moving on to AppleScript and Cocoa. AppleScript and Cocoa are not all new to each other. Since 10.2, I believe it is, we've been shipping AppleScript Studio which allows you to write basically full fetched Cocoa applications with real UIs and in AppleScript and you know, eventually people will hit the point where Display Dialog just isn't doing it anymore, so you want to, you know, real, real UI, progress bars, yada, yada, yada. OK, you could use AppleScript Studio.

The thing is that AppleScript Studio is not really Cocoa the way the rest of the world gets to see it. The Objective-C of Python, Ruby, all the people using Cocoa bridges. So to clarify this, we're going to look at a bit of an old example, Currency Converter. This one's been kicking around since the early NeXT days. Funny little thing, I've got it showing the Euro sign here, Currency Converter actually pre-dates the Euro by like 10 years.

So one of the things that Currency Converter is designed to show off is model view controller separation. This is a basic design pattern in the Cocoa world. The model is in this case, the actual math of doing the currency conversion. It's the application's view of the world. The view is the actual UI, the buttons and text fields, and the controller mediates between those two.

So we're going to look at the controller code here. So first, here's the studio version. In AppleScript Studio, you associate a script with an individual interface element. In this case, the convert button, and you do this using a special palette that's specific to AppleScript Studio. When the button is clicked, it sends a clicked message to the script and that-- so that handler has to be named clicked.

It's specific to the user interface gesture. And in order to refer to the various text fields, you actually refer to them in terms of their UI hierarchy, where are they laid out in the window. Which is a little awkward because it means when your UI changes, when it gets reorganized, quite frequently your code will have to change, too, which is kind of annoying.

So for comparison, let's look at the Objective-C version and I realize that a bunch of you are like, whoa, dude, AppleScript is on the sign-out side, not Objective-C, what are you doing here? Relax. The important, the important part here is the concept, pay attention to concepts. If the syntax really, really bugs you, try squinting a little bit so the punctuation goes away.

I find that works pretty well. So here it is. First thing is that in Objective-C you would define a class, and this is sort of the basics of defining a class in Objective-C. And you can actually define any number of classes in the same file, which may-- it gives you the freedom to organize your code one way or the other, whether you want to put them all in one file or split them across separate files.

The other thing to notice here is that it's inheriting from NSObject and its object is the base class that everything inherits from in Cocoa. The way the button action works, is that a button in Interface Builder-- you hook it up to an action method, and this action method can really be named anything.

So in this case it's called convert and a single object could contain a number of different action methods, so the one object could serve as the controller of a bunch of different objects. It's actually not possible in Studio. So again, more flexibility for you. And when you want to refer to the interface elements, the class defines a number of what are called ID outlets, basically properties, and these are connected in Interface Builder to the text field, to the text field elements, and Cocoa takes care of the rest, takes care of actually hooking, hooking these up at run time. So in your code, you just refer to the properties, and you never have to worry about exactly where these things are in the user interface.

So again, you, your code never has to be changed. The basic point here is that AppleScript Studio is not Cocoa the way everyone else sees it. There are a lot of places where you do not use standard Cocoa tools. They're kind of, a bunch of custom stuff Interface Builder that's only relevant to AppleScript Studio. You can't use a lot, you can't use most of standard Cocoa documentation, because AppleScript Studio has kind of its own way of expressing things, so you have to use the Studio documentation. You cannot use the standard Cocoa community.

One of the interesting things about bridged Cocoa languages like Python and Ruby is that the difference between Python and Ruby Cocoa code and Objective-C Cocoa code is pretty minor. You can still, if you know any one of them, you can read any of the others. So you can show, you know, Python programmers can show their code to, you know, an Objective-C programmer, and they can basically figure out what's going on. They'll like, well, OK, this is a little weird, but yeah, I recognized all this stuff.

That doesn't work in AppleScript Studio. It's just too different. And perhaps worst of all, you can't even use a lot of standard Cocoa framework, because AppleScript Studio relies a lot on custom glue code to provide that kind of AppleScript Studio special experience, and if it's not there, you just can't use the framework. Well, you can, actually, but you have to go through this raw call method of syntax, which is really, really gross. So the goal here is to make AppleScript development for Cocoa look like all of the other languages. So two steps to that.

First step is deprecating AppleScript Studio. Deprecated does not mean dead. You can still-- all your deployed applications still work, so your users aren't in any danger of being cut off any time soon. All the development tools are still there, so you can continue to maintain your existing projects. Some of the features have been hidden, in particular the AppleScript palette in Interface Builder. This is the magic defaults right command to turn it on. This is in the AppleScriptObjC release notes, by the way, so you don't have to write this down right now.

But you should be migrating your projects to the new stuff which is AppleScriptObjC. AppleScriptObjC is new framework in Snow Leopard. It is a Cocoa bridge built very much along the lines of the other language bridges like Ruby Cocoa or PyObjC. So and this gives you a much more consistent experience.

It's a consistent experience, consistent with the other development languages, so you use the tools the same way everyone else does. You can use documentation, because there's a minor syntactic fill up you have to do in order to actually use it. You can use the community like I was talking about before, because people can actually understand your code.

It's very much like what they're used to, and you can use any Objective-C API in the system immediately, no questions asked. It brings AppleScript into line with all the other languages so normal Cocoa techniques just work. Oh, and added bonus, it gives us a new acronym which is pronounceable in polite company. [laughter] So if you hear anyone refer to, if you hear, we've been calling it ASOC internally for months, so if you hear anyone say ASOC, that's what they're talking about. Marketing would like to see us use the full name, but ASOC.

So to show a little bit of how this works, we're going to do kind of a Rosetta Stone approach. We've got the converter controller code from Objective-C over here on the left and we're going to fill this in on the right with the AppleScriptObjC version. And two big things to know, one thing is that we're going to go line for line.

It actually matches up nearly line for line with the Objective-C. The other thing is that we did not add any new AppleScript syntax to do any of this. It's all existing AppleScript syntax. If you're a reasonably experienced AppleScript programmer, you've seen all of this stuff before, and it means basically the same thing. But it's now being applied to called Cocoa Objects.

So first thing is the class definition. So AppleScript's equivalent of a class is a script object, so you design a script object to make it inherent from NSObjects. The way you do that in AppleScript is, you give it a parent property, but the unique thing in AppleScriptObjC is now you give it a parent property of class NSObjects.

So this is an object that inherits from NSObject. Next we'll add the outlet properties. AppleScript has of course-- has properties-- that's just what they're called in AppleScript. So we define 3 of those and give them all an initial value of missing value. Missing value, two things about this. One is that missing value is AppleScript's equivalent to Objective-C's nil.

So anytime you see nil in Objective-C, think missing value and vice versa. The other thing is that, Interface Builder will pick up on any properties in your script that have an initial value of missing value and will treat those as ID outlets. So when you drag to connect in Interface Builder, they'll show up in that little pop-up menu, makes life a little more convenient.

The convert method in Objective-C turns into a convert handler in AppleScript and AppleScriptObjC handlers all use positional parameters, and the name here is a little interesting. So notice that the name of the original method is not convert, it's actually "convert:". That's what they call a selector in Objective-C. So the rule for translating those to AppleScript is you take all the colons and you change them to underscores, you mush them all together, that's the handler name and the parameters come after that.

This is, by the way, the exact same rule that Python and Ruby use for their bridges, so if you're familiar with one of those, then you know this immediately. When you want to call a method on an object, you simply invoke handler, a handler of that object. There are a few different syntaxes you can use to do this, using objects method, amountField floatValue in this case, and notice the parenthesis at the end. This is a function call after all.

There are a few different syntaxes you can use to do this. We're using this particular one simply because it matches the Objective-C order the best, and because it's the most, the most compact. There are other-- there are two others, we'll see them in a minute. Any of them works, of course, it's just a matter of taste which one you use.

Same deal for the rate field. And to do the conversion, this is a slightly more advanced version of that method that, that colon to underscore translation. So the original method in Objective-C was called, is called convertAmount:amount atrate:rate So that whole name becomes convertAmount_amount atrate_ as you can see on the slide. And finally, calling another method to set the float value.

You notice the setFloatvalue: in Objective-C, in, in Objective-C, so it's setFloatvalue_ in AppleScript. And here's another one of those syntaxes, that instead of saying objects method you can say tell object to method. Purely a matter of taste. I happen to like the way this one read. And that's it. That's our complete AppleScriptObjC converter controller definition.

[ Applause ]

So there are a few things you will need to know that are not in that Rosetta Stone example, and by the way, this is all in the AppleScriptObjC release notes, so don't worry too much about taking notes right now. You can look it up in the Snow Leopard reference library afterwards. First big thing is identifiers. Anything you use with AppleScript Objective-C has to be considered a user identifier as far as AppleScript is concerned.

This is one of the things about AppleScript that distinguishes very clearly between user identifiers and application-defined identifiers. Things that are effectively reserved by applications or AppleScript or scripting descriptions. So if you ever hit a conflict, you can force AppleScript to consider the thing, a user identifier, by putting it in vertical bars, pikes some people call them. So for instance, NSColor has a method called Set which sets the current drawing color.

But Set is already a reserved word in AppleScript used for a variable assignment. So if we're going to call it as a method, stick it in vertical bars, like you can see in the slide. So it's set and then the parenthesis to actually invoke the function. Same deal for balance.

Balance is another thing defined by AppleScript. It's a property of rectangles. So call it as a function, vertical bars. As a general rule, if you're ever in doubt, just throw them in, the compiler will strip them out if they're not necessary, and they won't harm anything if they're there.

So that's identifiers. Referring to classes in constants. This is something you'll have to do with some frequency. Classes are considered to be elements and constants, like numerated values, are considered to be properties of the current application. So for instance we can refer to current applications class NSColor or current application NSCalibrated and RGB color phase, say that 3 times fast.

Now, obviously throwing in the current application all the time makes the script a little noisy, more difficult to read, so a trick we discovered almost immediately is to hoist these things out into top level properties in your script and that way, so you can set them up initially, and in the body of your script, you just refer to NSColor or NSCalibrated or RGB color phase, so it's more compact, easier to read, saves you some typing. Referring to self, self and Objective-C is the same thing as me in AppleScript.

Me is the current script object. So if you want to get a property of yourself, you have to say of me or my, my radius, radius of me, either works. Methods like we discussed before, you tell, you can tell me, tell an object, me in this case, tell me to or my. So tell me to set me to display. This is how you tell a view in, in Objective, in Cocoa that it needs to redraw itself.

If you want to invoke your super classes, the implementation of a method, you want to call it the inherited version in Objective-C, this would be super method. In AppleScript, this concept already exists. Uses the keyword continues. So for instance, say continue init any time you write an initializer, the first thing you're going to do is continue init.

Data translation, this gets a little interesting. So there're a lot of basic value types that haven't put equivalents in Cocoa and AppleScripts, so things like strings, lists versus arrays, dictionaries versus records. In general, you can pass an AppleScript option, an AppleScript native type to a Cocoa call, and it just does the right thing. So for instance you can pass a, just an AppleScript double equivalented string anywhere that an NSString is expected. You can pass an AppleScript list to anywhere an NSArray is expected.

You, you could pass records where, where an NS Dictionary's expected. Keys that you use in the record turn into the strings keys in the NSDictionary and if you want to use a structure like an NSRange or NSReg or something like that, you can express that either as the record where you explicitly name the keys and notice their length is reserved by AppleScript by vertical bars again, or you can just do it as a list where you just list the members in order.

So both of those ranges there at the end, it's an NSRange, are of the exact same value, location of 0, length of 4. So that's when you're going from AppleScript to Objective-C Cocoa. When you're going the other direction, it's manual translation. Whenever you're passed a Cocoa object, it stays a Cocoa object by default.

The main point here is that that's so you can continue to call Cocoa methods on it. You cannot invoke Cocoa methods on what is actually just an AppleScript value. So in this case, we're being passed an NSString, and because it stays an NSString, we can call substring index on it, or you know, string by replacing characters or something, something to that effect, and the result of that will be another NSString. Now, if you actually need to do something AppleScript specific, you actually need a AppleScript string, you can use coercion. So you just say, as text, now it's an AppleScript string.

So you can pass it to say display dialog. One thing to watch out for here, I've seen some scripts that are kind of compulsive about coercing stuff that the first thing they do as soon as they call a function is as text, as number, as, as whatever. If you do that, then you are cutting yourself off from the Cocoa world. You're turning into an AppleScript value and can therefore no longer call Cocoa methods on that object. Only you can't use it at all, but you're cutting yourself off from it, so be careful from this, so be careful about that.

Now just because Cocoa objects stay as Cocoa objects does not mean that you cannot use AppleScript idioms on them. We went to some trouble to make these things work where they actually make sense. So for instance you can call order documents, order documents returns an NSArray and it stays an NSArray in AppleScript. But even so, you can still call repeat with DNDocs on it. You can loop over it as if it's a list.

You can get the first item, you can get the last item, those all work. If you are dealing with a property of an Objective-C object, like for instance the display name of a document, you can refer to that as if it's a, as if it's an AppleScript property. You don't even need the, you don't even need the parenthesis as, to show that it's a method call, it's just treated as a property, so you can even set it that way.

So very convenient. Last bit and I will confess this part is not in the release notes, NSError** parameters. There are a number of Cocoa calls that return an object by reference as an output parameter. Typically you see these with NSErrors that you want-- that give you detailed information about why a particular call failed. The basic function result just tells you that it did fail. The NSError tells you why. So if you want to call one of these things, then you pass one of two things.

If you don't care about the output value, and you just don't want to see it, pass missing value. Missing value is the equivalent of nil, so that just says, Naw, don't care, don't, fail, didn't fail, eeh, whatever. If you do care exactly why it failed, and you want to examine the object, then pass reference.

Remember reference is actually a class in AppleScript, and what this does is that the output object will appear as part of the function result instead of getting just the value, the basic function result, you'll actually get a list. First the function value, then the output parameter. If you had more than one output parameter, you'd get more objects in that list.

This is the same thing that Python and PyObjC use incidentally. For instance, in this case, we're calling RemoveItemAtPath_error. So the first one, just passing value, throw it away, who cares. The second one, pass reference and now we get a list back. The false tells us that it failed and then it's their object tell us why. Now, if you get invoked as a function that matches this kind of thing, this will happen, for instance, if you're trying to make your own NSDocuments sub-class because all the reading methods take an NSError** parameter.

AppleScriptObjC will pass to you kind of this magic object which represents the pointer, so you, that will either be missing value, which means, you know, whoever called you didn't care, so, that's the first thing you check. If our error, if our error's not missing value, then you can fill in by referring to the contents of that object, so make an NSError object set contents of out error to the error and that's it. This same technique actually works for any pointer style param-- output pointer parameter.

But NSError is the most common case. So enough of me babbling at you. Let me get Michael Gorbach back up here to show you a bit about how it's done, what it looks like. Michael.

OK, so best way to explain ASOC is to, to sort of compare it to the way that we used to do things in Studio, and I think if we do that, it will really show you what the advantages are moving to the ASOC world. So that's what we're going to do. We're going to start with an example called Task List. So it is a very simple app.

It is a simple task as it allows you to enter a few things you need to get done, sort them, set priorities, and so on. Maybe you've seen this before. So we originally wrote this as a Studio example of filling a table view with data and using the data source features of Studio. So Cocoa developers used to have to do things this way, too. But, recently they've gotten a feature called Bindings, which really saves you from having to write a lot of this code.

How much code? Well, if you look at this example, kind of goes on and on and you know, on, and it's about 250 lines of code even without the long comments here. So what if you could get rid of all of this code, or almost all of this code? Bindings can do that for you. Bindings is topology that Cocoa people have had for some time and now we can bring it to you when you move to ASOC. So we're going to take this example and rewrite it using bindings and using ASOC or AppleScriptObjC.

That's all.

[ Applause ]

Seven lines of code to do pretty much the same thing that the original Studio app did. I'm going to show it to you to make sure you believe me here. And Bindings is making this magic happen. Binding is set up in the name. We're not going to discuss them in detail here because this isn't really a Binding session, but remember, Bindings in Studio-- in ASOC work just the same way that they work in Cocoa.

Ask any Cocoa developer, watch any Cocoa session, look at any Cocoa example and you figure out how to make this happen. So this is a pretty good example, but it's showing you Bindings, and it's showing you that ASOC can make you more productive and cut down on the code you have to write.

But, writing less code is not the only thing that ASOC can give you. ASOC also gives you the access to the functionality of all our system frameworks. Everything that every Cocoa developer has had access to for years, everything you recreate, you can get your hands on it, and you can get your hands on it immediately. So this example's all right, but now if I start it up again, my tasks are gone, it's not really very persistent, doesn't show me my tasks I need to see them, it doesn't show me them in I-Cal, it doesn't show me them in Mail.

It's not really much use for anybody. But it turns out we have a Cocoa framework on the system for this purpose, it's called CalendarStore. And what it does is, it integrates with Mail's tasks and I-Cal's to-dos, and it shows you them right where you need them, and it allows the apps to control that list. So we're going to add a little bit of code to this example and rewrite it and add it at code so that it works with CalendarStore. So the tasks that we put into this app synchronize with the ones in I-Cal.

So this actually is the CalendarStore version of the example. There's two things I wanted to point out about the code, but before I do that, I just want to run it for you. We added-- to make this happen we added about 60 or 80 lines o`f code, one more file. So it's still about half the size of the Studio example, and it does a whole lot more. And here's what I mean, so, you know, we can add a task. If you go to I-Cal, there's our tasks. We can add a few more, and set a priority.

As soon as you go back to I-Cal, there they are.

[ Applause ]

So, there were a few things that I wanted to point out about this code. First thing to note is that Cocoa-- is that S-group has created an app delegate for us here and there's some entry points and exit points that you're going to want to know about when you start writing ASOC apps. First one here is awake from nib.

So it looks just like the awake from nib that you used in studio, but you know, we've lost the spaces and we've changed the capitalization to match the Cocoa way of doing things, but it is your entry point for when your options get exploded from the nib, which happens generally when your program starts. Another important thing to know is application will terminate. This is a method that does get run when you're program is about to exit and it's useful when you need to save stay or do some cleanup work before you get out.

There's also will become update and will reside active if you need to do some active when your app activates and deactivates. So we can go through a little bit of the CalendarStore code which is in another file, to point out some of the ASOC syntax that Chris mentioned earlier. Over here we have the shortcut for classes that Chris discussed.

We're just defining some properties in the top level of the script so that it's easier, and so that we write less code later on. We have a parent to indicate what class we are sub-classing, and we have some properties which will be filled in later. So one thing to know on this slide, is that we are calling addObject, which is a Cocoa method on a Cocoa object or Objective-C object, but the parameter that we are passing is actually an AppleScript record. This is the really convenient automatic conversion of parameters that Chris mentioned. So the AppleScript record will get converted into a Cocoa or Objective-C dictionary and everything will work just as expected.

We'll use regular AppleScript syntax to reference our keys. Another thing to point out is that over here we're using a repeat loop and tasks is actually not an AppleScript list, but an NSArray, a Cocoa or an Objective-C object. So many of the common constructs that you use in AppleScript have been updated now so that they work as expected with certain Cocoa objects.

In these two eyes, it's very convenient that we can use access we can use regular AppleScript property accessers to get at the, at the properties of Objective-C or Cocoa objects, ACaf is an object from CalendarStore and we're just accessing its priority and its title and we can even set them with very similar syntax.

Finally, I want to point out the use of NSError as Chris discussed in a few slides ago. So this is CalendarStore's remove task error method which may fail and may return user visible error of some kind so you can display what went wrong. We're passing reference here which is a class and we're interested in getting the result back. So the result is actually an AppleScript list. We check item 1 which is going to be a void to indicate whether the method has succeeded or failed and if the method did fail, we will get item 2 and that will contain our error.

So we showed you an ASOC an example here to try to explain that ASOC can make you more productive and can really enhance the capabilities of what you can do for your users. You really get access to areas of the system that you've never had access to before.

But, we want you to start writing ASOC code this week. We want you to really dive into it. So the best way to do it, we just had to show you another example that can take you through creating an ASOC project from scratch so that you know where to start.

The example we're going to do is actually called Dot View. Dot View is an example that many Cocoa developers probably seen before. It's just a simple example that draws a dot with a particular color and radius on the screen. Why are we showing this to you? Well for you Studio developers, doing graphics primitives-- even simple things, was almost impossible in AppleScript Studio. So now you can do it, now you can do it easily, and I just wanted to show you how to make that happen.

So we're going to create Dot View from scratch. We're going to create a new AppleScript Objective-C application. We have a beautiful icon here and we can call it Dot View. So Xcode will open up and it will create a skeleton application delegate for us which will include some of the entry and exit points that I discussed earlier. The, there's also an application we'll finish launching and prepoint which is separate from the nib and also get started when your app has finished its loading process.

And we're going to put together Dot View step by step. So the first thing we want to do is add a few properties, which are, as I disused already, shortcuts so we can type less during the rest of this script. We'll be having these two Cocoa classes often during our code and we just want to save on some typing, or maybe save demo monkey some typing. So we're going to add another set of properties which are going to be key to the app, and this is going to be the parameters that we use to draw our circle.

We have a center, a radius and a color.

[ Silence ]

All right. So actually, small change. We are writing a drawing out, so what we're going to need to do is sub-class and skew which is Cocoa's primitive class for doing drawings. We're going to create a new file and it's going to be an add FC sub-class.

Xcode is going to help us out. Going to call it, Xcode is going to help us out by creating a skeleton for the main, the important methods that NSU sub-class has to implement. There's an equith frame, which is going to be the code that's going to get run when your view is first created and there's draw act which is going to be the code that is going to get run for the main drawing part of your view.

It's going to get run also. So you can do what I did earlier, add our convenience properties here, and create the first 3 parameters that we're going to use to draw a circle. The thing that I didn't get a chance to point out here is that we have X and Y coming into the center.

This is an example of using, of using point and, in Cocoa point in AppleScript syntax so we have a list here which is going to get converted to a point as an Objective-C expected. So we could fill in our initialization code to set the 4 parameters that we're going to need.

One thing to point out here is, we're using continue to call out to our super classes and put implementation of an equith frame. Very important that we let our super class finish its initialization before we start doing our work. Another important point is that we are calling return me here. Me is like self in Objective-C. It's the object in question. It's the object's method that's being called on and we do want to return it from our initializing.

Finally, you want to add some code to draw a rect. This code uses an aspasure [assumed spelling] path which is a Cocoa class that does basic line drawing for us. I'm not going to go into the detail of how and aspasure path works, but again, as I said earlier, you can go to the Cocoa Objective-C documentation, you could figure out how this works and you can translate it quite easily, line by line from Objective-C into ASOC.

It's much easier than you would expect. And we will add a few more methods to make all this happen, we need to track the mouse and we need to make sure that we draw and redraw our view when we set the radius and when we set the color. So we've got most of the code done, but we still need a nib.

About, with regards to nibs, we need to-- we know that in ASOC nibs works in the same way as they do in Cocoa or Objective-C. There's no special Studio weirdness going on in terms of how you create nibs. So just to prove that to you, we can take the nib from the Cocoa version of this project, we can drag it right into this one and it's going to work just fine.

So I'm going to go ahead and delete the example nib that the template has created for us, and I'm going to find the Cocoa nib, and I'm going to drag it into the resources here and I'm going to copy it. I'm going to save our code and if the gods are with us, we will successfully run.

And we do.

[ Applause ]

So there's a start for you in ASOC. Give that some colors, adjust the point, the center of the circle and so on. So pulling examples from Objective-C to ASOC is very easy. You gain new capabilities you never used to be able to do line drawing in any kind of the same way. It's a pretty big deal. The last thing I want to point out about this code is, it's significantly shorter and easier to read than the original Objective-C example.

Partly because, you don't have to deal with memory management, we synthesize access and set aside the properties for you. We use a garbage collection. It's a lot easier than things used to be in the world of Objective-C and of course we have the AppleScript syntax that everybody loves. We know you do. Thank you, and I'll give the stage back to Chris.

So all sorts of things you can do now using AppleScriptObjC. That said, there are a few little caveats I'm legally obliged to tell you.

[presenter speaking extremely fast] Void where prohibited. Some assembly required. Action figures not included. This is not an offer to sell securities. Any resemblance to real persons, living or dead, is purely coincidental. No animals were harmed in the testing of this product. Contents may settle during shipment. Use only with proper ventilation. Keep away from open flames and avoid inhaling fumes.

Do not use while operating a motor vehicle or heavy equipment. Apply only to affected area; if condition persists, consult your physician. Amy be too intense for some viewers. Post office will not deliver without postage. Best if used before date on carton. Times are approximate. Slightly enlarged to show detail. Colors may fade over time. Content has been edited for your screen.

Not affiliated with the American Red Cross. At participating locations only.

[ Applause ]

I was careful to select things that are sort of technically, technically true for AppleScriptObjC, but of course these are not the important ones. The important ones, first off, this is not, this is not a free transition for you admittedly. There is work that AppleScript Studio people will have to put in if you're going to transfer your apps over.

You will have to rewrite a lot of code. However, as you saw from the examples, rewrite quite frequently means throw away, and even where you do have to rewrite, we've typically found that the AppleScriptObjC code is about 30 to 50% smaller that the equivalent Studio code. There are a few things that do not work correct, do not work.

We concede, just so you don't waste your time. First, you only get access to Objective-C functions, not plain C functions. The second big thing is that structure bridging only applies to NSPoint, NSSize, NSRange and NSRect. Now this covers just about everything that all the structure types that exist with the kit, with the sole exception of NSDecimal-- NSDecimalNumber. So I'm not giving any guarantees about those 2 for 2, for the final version.

However, there is one big one that we are definitely fixing because it just didn't quite make the seed in time, it is all supposed to be 64-bit, but there's a fairly nasty little bug with garbage collection so it reaps objects prematurely. So for the time being, run at 32-bit. We know exactly where the fix is, like I said, it just didn't make the seed in time.

We will fix it, but in the mean time, stick with 32-bit, you'll be a lot happier. So like I, like Michael was saying, the big win here is you get access to all of Cocoa, and I don't just mean the code, but that's a huge part, you get access to convenience features like Bindings. You get access to power features like CalendarStore. Stuff you really couldn't do before.

You get access to new features like we don't know, because we haven't created them yet. The point is, we don't have to know. As soon as they show up, as soon as an interface is published, you can use it along with all the other Cocoa programmers, and at the same time, it is still regular AppleScript. You can do all of the AppleScripting stuff that you're used to.

You can control other applications, you can use all your existing AppleScript libraries, it all just works. So it's a very, very nice combination and really brings you into the same world as all the other Cocoa programmers. So AppleScript winds up being a first class citizen, not a sort of, like, weird cousin in the corner like AppleScript Studio was.

To sum up, AppleScript is future compatible now. It's 64-bits, so it's compatible with, so it's fully compatible with hardware going forward, and it's now thread-safe and that means GCD safe so all this multi-core, multi-threading craziness, you can use AppleScript right along with it. If you want to create full blown applications like I said, display dialog just ain't doing it for you anymore, write a code co-application and this means write a Cocoa application using standard Cocoa techniques.

Use the language you want, whether that be AppleScript, you know, if you really want to switch to Objective-C or Python or Ruby, you can, it's very straight forward since you're using the same coding techniques as everyone else, there's a consistent experience across all Cocoa development languages, so you can use standard tools, you can use standard community, you can use standard documentation, you just have to learn that little syntactic translation.

You can do that in your head with a little practice. AppleScript Studio is deprecating, doesn't mean dead, you can keep using it for now, but try to move to AppleScriptObjC, that's where all the action is going to be in the future. Should you have further questions you can contact Matt Drance, the Framework Technologies Evangelist.

Sal Soghoian is the AppleScript product-marketing manager. And if you want to read about it yourself, go to the attendee site and in particular go to the Snow Leopard reference library. That's where the-- and look in the release notes section for AppleScript. That's where the AppleScript release notes are, that's where the AppleScriptObjC release notes are. 25