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: wwdc2008-525
$eventId
ID of event: wwdc2008
$eventContentId
ID of session without event part: 525
$eventShortId
Shortened ID of event: wwdc08
$year
Year of session: 2008
$extension
Extension of original filename: m4v
$filenameAlmostEvery
Filename from "(Almost) Every..." gist: [2008] [Session 525] Cocoa Devel...

WWDC08 • Session 525

Cocoa Development Using Scripting

Integration • 41:54

Cocoa development isn't just for Objective-C programmers. Learn to create Cocoa applications using your favorite scripting language, whether it be Python, Ruby or AppleScript. In addition, find out how to control Apple Event-aware applications from Objective-C, Ruby, or Python through the Scripting Bridge. Come see how Mac OS X Leopard makes application development and interaction easier than ever, from a number of languages.

Speakers: Chris Nebel, Barry Langdon-Lassagne

Unlisted on Apple Developer site

Downloads from Apple

SD Video (510.5 MB)

Transcript

This transcript was generated using Whisper, it has known transcription errors. We are working on an improved version.

Okay, this is Cocoa Development Using Scripting. Thank you all for coming. Actually, it's fairly impressive. I've never seen a room this full before for one of my style. I'm Chris Nebel. I'm one of the engineers who makes all this stuff work. And yes, that is what it says on my business cards.

So if you think of Mac OS code, Mac OS development as like a big metro area, say San Francisco, Then Cocoa, the system frameworks, those are city center, downtown. This is the hub of all the development. This is where you go when you want the system to do something for you.

Client code, then, stuff like your applications, is distributed around the outlying areas. Now, if you're writing in Objective-C, then you're just a bit further south down the peninsula, like Daly City or somewhere. Getting to Cocoa from here, you need the system to do something for you, you commute in, you get what you need, you come back. Getting to Cocoa from Objective-C is trivial. You just stroll across the border, which you probably won't even notice there is a border.

But there are other interesting areas too, with other interesting things in them. We've got other scripting languages, we've got interesting services which are not strictly part of Cocoa. How do you get to these things? This isn't just a matter of walking. So the answer in real life, of course, is you build bridges. And that is the answer in the code world as well, except that our bridges are made out of Objective-C.

So we'll spend some time talking about what you can do with a bridge, how to use Cocoa from a scripting language, and how to use scriptable applications from Cocoa. And we'll talk a bit about exactly how the bridge works, how you can build one of these things. So first off, bridging two languages.

So you want to write a Mac OS application. You've got great idea, new killer app. The basics of what you need. First off, use Cocoa. Cocoa is the system framework on Mac OS X. This is where we put all of our good stuff. There's lots and lots of stuff in here. AppKit for doing all your UI, core data, core animation. The list just goes on and on. Awesome tools to go with it. There's Xcode, Interface Builder, Instruments.

[Transcript missing]

You know, there are various reasons for this. Maybe you've got some big hunk of pre-existing code, some other language you don't want to mess with rewriting this. Maybe you're using some specialized framework that doesn't have an equivalent in Cocoa, like Twisted for Python. Maybe, you know, you just prefer something else, okay? That's okay.

The first thing to realize is that Cocoa is not the same thing as Objective-C. Cocoa is a framework. Objective-C is a language. You can pull those two apart. The tricky bit is that Objective-C is not just a language. It's a syntax and it's a runtime, and you can pull those apart, too. If you can call the runtime, then you can get to any Objective-C service, which means you can get to Cocoa. And the runtime has a straight C API.

So anything that can call plain C functions, which is just about everything, can call the runtime and therefore get through to Cocoa. And this is where a Cocoa bridge comes in. A Cocoa bridge handles all the grunt work of calling the runtime and translating data back and forth from Cocoa to wherever it is you are actually interested in being.

So there are Cocoa bridges for a variety of languages, and now we'll take a look at a few. And we're going to take kind of a Rosetta Stone approach to this, using Currency Converter. If you haven't seen this before, Currency Converter is the basic introduction to Cocoa tutorial application.

So we're going to look at some of the code. And this is what it looks like in Objective-C. This is part of it anyway. This is the controller class. One of Cocoa's key concepts is model-view-controller separation. Model is what your application actually does. View is what it looks like on screen, Windows and whatnot. And controllers mediate between the two.

So this is the Objective-C code for the controller class. So we'll compare what this looks like in various languages. Again, this is Objective-C. And the three particular things to notice here are, one, the class declaration. This being C-based, it's split into an interface part and an implementation part. Those would go in separate files in Objective-C. In the interface part, there are declarations for three instance variables, IB outlets. These will get connected to text fields in the interface. So you can see the text fields from code.

And the third bit is the action method. This gets called when we press the button, and this handles the work of getting the information out of the text fields. That's the second and third lines. Does the conversion and then puts the result back into the third field. And you might be looking at that convert amount bit and thinking, "Why on earth is he creating an entire object just to multiply two numbers?" Because that's really all this is going to do. This is model-view-controller separation going on. Yes, it's trivial. Yes, it's a bit silly at this size, but it shows separating out the models. So that's how the tutorial is written.

So first off, let's look at Python. How does this look in Python? The bridge for Python is originally called PyObjc. It's quite old. It actually predates Mac OS X. In these days, it's built into Leopard. It's got full Xcode and Interface Builder support. There are project templates in Xcode. Xcode knows how to do syntax coloring and code folding, etc. Interface Builder knows how to read Python files so it can auto-fill fields for you. There are lots of examples and developer examples. This is what the code looks like. Three bits here. Here's the class declaration. Pretty straightforward. It inherits from NSObject.

Here are our three instance variables. The objc_ivar is just a bit of magic to let the Python interpreter know that these need to be hooked up to Objective-C. And finally, the convert method. So again, get two values, do the conversion, put it back. Pretty much like the Objective-C version, but with a little less memory management going on.

Next, Ruby. The bridge here is called RubyCocoa. It's available as open source back to Panther. Again, it's built into Leopard these days. Again, full Xcode and interface builder support, all the good stuff, lots of examples. And the code, again, looks pretty much the same. There's just syntactic differences thanks to working in Ruby now. Here is the class definition. Here are the three IB outlet instance variables. And our convert action, again, the same four lines. And finally, we have AppleScript. This is called AppleScript Studio. It's created back in Panther.

[Transcript missing]

And the reason for this is that Studio just works kind of differently from all the others. And that actually causes a bunch of problems. The basic point is that Studio bridges directly to AppKit. It doesn't really go through Objective-C at all. There's a lot of things that are just different in Studio. There's a dedicated palette for Studio in Interface Builder. It's only used for Studio. When you're using Studio, you ignore three other panes in Interface Builder that you would ordinarily use. You, like I mentioned before, you refer to controls using the UI hierarchy instead of using outlets.

That's kind of a serious problem because it means that when you reorganize your interface, if you put a control inside a box, your hierarchy is changed and now your code needs to change as well. You don't have that problem in the other languages. Actions are referred to not using target action like you normally do, but instead using fixed names that describe the particular action, such as "clicked" or "on scroll wheel," something like that.

It goes further, too. There's no KVC support, which means you fundamentally can't use outlets. And you also can't use Cocoa bindings, which is a really useful feature that lets you save quite a bit of code in some cases. And perhaps most problematic of all, there's custom glue required for every class that you want to write in AppleScript Studio. And we have to provide that glue. So what's available in AppleScript Studio always lags behind what's available to the rest of the system.

To deal with all this, we are adding something new in Snow Leopard. We are taking a big step sideways. and introducing a bridge that we're calling internally, at least, AppleScript Objective-C. It's just another Cocoa bridge. It will be built into Snow Leopard. This is a true Objective-C bridge like the others for Python and Ruby, which means that the usual Objective-C techniques just work. You use normal interface builder, you use outlets, you use bindings. Everything is exactly the same as it is in all the other languages. It's exact parity. All the normal Cocoa techniques just work.

Now, to show this off, I'd like to get Barry Langdon-Lassagne up here. And we will run through Currency Converter and a few other things in AppleScript. So if we can switch over to the demo machine, please. Hi, Chris. Good afternoon, everybody. That's not what shows up on my business card.

So all of the examples and sample code we're going to show you, this will all work on the version of Snow Leopard that you guys were seated with this week. But I'm not sure if the examples have been uploaded yet to the website for this session. Real soon now. Real soon now, yes. So sometime this week, if they're not already up there.

Okay, so we're going to continue on with Currency Converter. So if we open the project here, there we go, and open the script, we can see what this looks like. So the first thing up at the top is that mystery model class, the MyConverter that we were seeing before. This implementation should surprise nobody. It just multiplies the two numbers.

The part we're really looking at is the controller class. And now this looks a lot more like what we were seeing before, a lot more like the Objective-C version. There is ScriptMyController, an AppleScript script object appears as a class as far as Objective-C is concerned. We've got our three properties, instance variables. These are simply initialized to missing value, which is AppleScript's equivalent of nil. And finally, we have our convert action, which is now called convert again, and again, the same four lines.

And if we look at a little more detail at some of these, take the first line, a simple assignment in AppleScript. And in particular, look at what it's assigning to, RateField's float value. RateField is a reference to an Objective-C object, and it's going to send it the float value message. And that is simply the Objective-C selector name, float value. And because it's just the regular Objective-C selector name, we can just option double click on it and get the documentation for it.

We're actually using the NS Control version. Read all about it. Lovely. There it is. And to compare, like I said, it's the selector name. If we look at the last line, set float value, you'll notice it's set float value underscore. In Objective-C, the selector name would have colons in it, but colons aren't legal in AppleScript, so they get turned into underscores instead.

This is the same heuristic that the Ruby and Python bridges use. You take the selector name, turn the colons into underscores. That becomes the function name and the parameters appear inside parentheses.

[Transcript missing]

So that's the code, which again looks very much like the Objective-C code and like the Python code and like the Ruby code. Now we have to hook it up in Interface Builder.

We've got the interface already laid out here, and we've got an instance of my controller already in the Nib. We need to actually connect this to the interface fields. So if you pop up the Connection Inspector, this is one of my favorite features in IB3. We can see all the outlets that we have, which correspond to the properties in the script and the action, which corresponds to the handler. So if we wire these up, connect the outlet field to the first text field, Second one. You've never seen Interface Builder? Did you guys just get here? That's the third one. And finally, the Convert action method to the Convert button. Lovely. Save, build, and go.

[Transcript missing]

"$1.25, great. 25 simoleons, I feel so rich." So there you go, that works. And the thing to note here is that this is exactly the same steps that we would go through in the Objective-C tutorial or what we would have done in Python or Ruby. The interface builder part is exactly the same. It's not different like it was in AppleScript Studio.

So how many Studio developers have we got here? A little show of hands? Okay, a few people. So the Studio developers may be saying now, "Okay, parity, that's nice and all, but that code was longer than what I had to write in Studio. I'm not impressed." Fine. We have access to all of Cocoa here. So let's do the same currency converter, but this time we're going to use Cocoa Bindings. Cocoa Bindings is a very nifty feature which was introduced back in Panther that lets Cocoa fill in a lot of the controller code for you.

So here's the script that we have that uses bindings. And now it's a lot shorter. And this is all model code. Notice we still have three properties, but they're not references to text fields anymore. They're just the numbers.

[Transcript missing]

So let's open the nib and do that.

So this time, instead of using the Connections panel, we're going to use the Cocoa Bindings Inspector. We've already got our model object, and we've also got an object controller. This is the Cocoa class that does the controller code, which we used to have to write by hand. So if we pick the first one of the text fields, We can go to the Bindings pane here and say this text field gets its value. It is bound to the Object Controller and with a keypath of Amount.

And now we'll do the same thing. The second text field is bound to the object controller's exchange rate. And finally, the last one bound to total. And the Connect button will wire up the same way as we did before, connect that to my model's convert method. OK, save, build, and go.

All right. Chris Nebel, Barry Langdon-Lassagne Okay, same numbers as before, 20 bucks, simoleon 25 to the dollar, convert, and there you go. So currency converter now in, I think, eight lines of code, not bad. So now the studio people are saying, OK, it's shorter, but it's still just currency converter. Try something hard like a table, smart guy. Let's do that. You're in luck. I have one right here. How astonishing.

Tables are, of course, very useful. Turn up in all sorts of situations. They can also be fairly complicated to code for. But Cocoa Bindings makes it relatively simple. Let's take a look at the script. Again, Bindings let us write just the model code. What we're doing here is kind of an address book on the cheap. It will be a table of people -- first name, last name, and e-mail. And we're using just basic properties to hold the first name and last name.

But then for the e-mail property, we're using a function to compute it on the fly. We'll mash the first name and last name together and go fetch the e-mail address out of address book. This is what AppleScript is good at, is talking to other applications, so it talks to address book. And just in case this person hasn't got an e-mail address, it's wrapped in a try block that will return nothing if it fails.

So that forms the basic person model object. The other object, my model, is simply here to hold a list of people. That's the people property. And we've also got, mostly to save us typing time, an awake from nib method. This will get called automatically by Cocoa when we load the nib. And again, it's just got straight AppleScript in it as well. Yep. OK. So this will simply grab some people out of Address Book to populate the table for us, so we get to see something when we launch. Everything else happens in Interface Builder.

So we've got the table already laid out, and we've got my model instance there. The first thing we need is an array controller. We saw an object controller before. Cocoa also has a class to manage an array of objects. So the first thing we need to tell the array is what it's an array of. So if we go to the You can tell it's going to be managing an array of class MyPerson, which matches the script object that we defined first.

And we fill in the keys we're going to be interested in. This isn't strictly necessary, but it saves us some typing later. So first name, last name, and email. Great. So now we bind that array controller. Where is it going to get its array from? We bind that array controller. Switch to the Bindings pane.

And we bind the content array to my model. And the people key, which matches that people property in the script. Okay, so now the array controller knows about the model. Now we have to teach the table about the array controller. So we do this one column at a time. Take the first column, and its value is going to be bound to the array controller and its first name, keypath.

"Second column, similar, bind to the array controller, and this goes to the last name. And last column, email. And the fact that email is really a function makes no difference as far as Cocoa is concerned. It doesn't distinguish between a plain property and a function that takes no arguments."

[Transcript missing]

And there it is.

It's already populated out of our address book. It's fetching the email. If we click the plus button, we'll get a new row. Chris Nebel, Barry Langdon-Lassagne And that in, you know, about a page worth of code. Not bad. And ArrayController gets us some extra behavior for free, like sorting of columns. We didn't have to write any code to do that. And it gets us some additional behavior as well.

Let's take this one step further and do something you really can't do in Studio. We're going to add a search field. We've never added Glue for NSSearchField in Studio, but hey, this is just Cocoa, so we can do a search field. So the first step, obviously, is add a search field to the interface. Drag that in.

And NSArrayController is so cool that we're not going to have to write any code to hook this up. We're not going to have to add anything to our script. All this happens using bindings. If we scroll down a bit, we get to the Predicates section. Search fields and array controllers know about each other through predicates.

So we bind this to the array controller and the predicate field. Admittedly, this is a little code-like, but the syntax is all documented in NSPredicate. We need first name contains dollar value. Dollar value is simply whatever's been typed into the search field. Or last name contains value. We don't want to annoy people with case sensitivity, so we'll put a little qualifier on the contains operator there. Cd means not case sensitive, not diacritic sensitive either.

And that's it. This is all done in the Nib. If we build and run, we should get our same table as before and happily filter down to Larson. Pretty simple. It works. Okay. Thank Back to slides, please. So, summing up for Cocoa Bridges. The basic point here is that you can choose the language that works for you. You are not obliged to use Objective-C, you are not obliged to use Python, you are not obliged to use Ruby, or whatever. Whatever it is that is right for your project, your personal preferences, whatever. It's okay.

Bridge languages work great for casual development, in-house development, even shrink wrap. There are people shipping shrink wrap applications that are actually built in Python. And it's awesome for experimenting. One of the great things about using an interpreted language to run Cocoa is that you often have an interpreter. You can just type a line and see what happens. It's my favorite way to experiment with new frameworks now.

The three that we've mentioned, Python, Ruby, and AppleScript, those are the ones that are built into the system, but there are others besides, typically available as open source. There are bridges for Perl, there's a bridge for Lua, Common Lisp, there are a couple of dedicated languages, Fscript and GNU, which is kind of a scheme dialect. Probably a bunch more I don't even know about. So, awesome stuff. Try it out.

So that's Cocoa Bridging. Now let's talk about bridging to services, specifically bridging to scriptable applications. Scriptable applications have been around in Mac OS for a long time. They actually date back to Mac OS 7. If you are writing an application yourself, we highly encourage you to make it scriptable. There's a session tomorrow at 2 o'clock on doing precisely that. I believe it's called Making Your Application Scriptable. And the traditional way you control a scriptable application, or at least the historic way, is by using AppleScript. AppleScript was designed specifically to talk to scriptable applications. It's very good at it.

But you're a real developer. You're writing a real application in Objective-C. How do you do this? There's nothing really magical about NSAppleScript that lets you control scriptable applications. All it's really doing behind the scenes is it's constructing Apple Events, a kind of IPC protocol, a little remote message send. And that's what iTunes is really paying attention to. And Apple Events have a plain C API, so really anyone can use them.

And there's even an Objective-C wrapper for Apple Events called NSAppleEventDescriptor. So if you code using these, then this is basically as efficient as possible. You're not taking any of the overhead for the AppleScript interpreter. It's just the message sends. So very fast, very efficient. Say you want to get the name of the currently playing track in iTunes.

You know, lots of applications. The basic point of using a scriptable application is that you can leverage other applications, right? You can get them to do features for you. So an iTunes controller is a fairly common example. Say you want to get the name of the currently playing track in iTunes. NSAppleEventDescriptor, great. All you have to write is this.

So what people actually do is they write an AppleScript. And they run it from within their application using the NSAppleScript class. So it's obviously a lot simpler to write. The thing is it doesn't work very well. Because now you are taking the hit for the AppleScript interpreter. So you impose a bunch of extra time, use a bunch of extra memory.

It doesn't integrate all that well with Objective-C. What we really want is just an NSString eventually, but that's not what we get out of NSAppleScript. We get something else, actually another NSApple event descriptor, from which we have to extract a string. So what we'd really like is something that is simple to use like NSAppleScript, ideally even simpler, and yet has the performance of NSAppleEventDescriptor.

And that's what Scripting Bridge is all about. Except this was introduced in Leopard, and we're not calling it Scripting Bridge anymore. Scripting Bridge was a fine name as long as we always thought scripting meant application scripting, which it kind of used to, but obviously we're using scripting for a lot more now, a lot of different things.

So, Scripting Bridge was a bit too confusing. We're naming it a bit more specifically now. It's the Apple Event Bridge. I'm probably going to screw this up at least once while I'm talking. Bear with me. So, here's what it looks like. First step is you generate a header for the application that you're interested in, in this case, iTunes. So this defines a bunch of classes.

[Transcript missing]

And if you happen to like Objective-C 2, the property .syntax works great with that too. Even saves you two more characters.

And because this is simply an Objective-C Cocoa service, it works with bridged languages as well, except that you don't have to bother with the first two steps, because you don't really need a header and there's no link phase. Here's what the same code looks like in Python. Again, get a reference to iTunes. Print iTunes current track name. And same thing again in Ruby.

And to show off something a bit more complicated, if I can get Barry back up here, we'll do another demo. So one of our evangelists had an interesting problem, that he's got his home stereo hooked up to his iTunes library. The thing is that the standard infrared remote doesn't really work very well for him, because he's frequently out of line of sight.

He's actually got speakers in lots of different rooms of his house. He's got speakers in the living room, he's got speakers in the den, speakers in the backyard by the jacuzzi, speakers underwater in the jacuzzi, whatever. In the basement with the bowling alley. Yeah, that too. Is Matt here?

[Transcript missing]

He happens to know Ruby, and Ruby has a nice package that lets you write quick and dirty web servers.

So here's what some of the code looks like. So the web server package is called Mongrel. So it uses Mongrel on one end to do all the webby kind of stuff. And then it uses Scripting Bridge, Apple Event Bridge, on the other side to talk to iTunes. There. Yeah, we'll have to fix that in the online version too. It's spelt Scripting Bridge, it's pronounced Apple Event Bridge.

So there's the includes. One of the first things it does as part of its initialization is it gets a reference to iTunes, similar to what we saw on the slides. And then the various controls on the web page that it presents are hooked up to iTunes actions. So, for instance, here is the next button handler that when you push the next button on the web page, it simply tells iTunes, go to the next track. And if you're not already playing, then start playing. and there's even some eye candy features in here. There's a bit to go fetch the album artwork from iTunes, turn it into a JPEG and stick that as part of the web page.

So let's see how this works. I believe we have the server already fired up. Yep, it's running. OK. And we don't have an iPhone projector here, so we're actually going to use the simulator for this. If we go to Safari-- Here's our web page. Press play to start iTunes. Let's do that. iTunes launches and starts playing.

[Transcript missing]

We can pause that. If we skip to the next track, it starts playing like we saw in the code.

I absolutely love this song. It's actually by a couple of old friends of mine, but we do not have time to listen to the whole thing, so pause again. But it is available on iTunes. Okay, thank you very much. Oh, I think -- Oh, wait, do we have one more thing? I have to try this to see if it works for real, if I really can use this as a remote. We'll see. This is the part where I need demo gods.

Can you hear it? Next song.

[Transcript missing]

So Apple Event Bridge. Like I said, the basic point here is make other applications do your work for you. If you need to send mail to something, send an attachment, you can tell mail to do that. You need to file a photo, tell iPhoto to do that. There are entire applications that have been built on top of Excel or OmniGraffle or OmniOutline, which is effectively a display engine.

And if you're going to do this, if you're going to script other applications, do it efficiently. If you're using built-in logic, use Apple Event Bridge. This is the fast way to do this. NSAppleScript still has its place, but its place is for running user-supplied scripts, stuff that is not built into your application. You don't know what it is at build time. If it's built into your application, use the Apple Event Bridge.

So how the heck does all this stuff work? So the basic game with all of these is that you've got two different runtimes, which are not inherently compatible. The game is to make each side think that it's talking to more stuff just like it. Nobody here but us chickens.

So Cocoa objects know how to send Objective-C messages. Python does not understand Objective-C. This is where the Cocoa Bridge comes in. The Cocoa Bridge will create these little shells of Objective-C around the object. So from the outside, they look like Objective-C. In reality, the message hits this. It gets translated into something that Python can understand.

And then going the other way, It's basically the same thing. The Cocoa objects get wrapped in these crunchy little Python shells. So they look like Python objects, but they're really not. The message gets translated again going in. So this presumes a fair amount of introspectability and dynamism in your runtime, which fortunately Objective-C has, and so do a lot of the scripting languages.

So there are four basic capabilities that you need. And it all comes down to inspecting existing stuff and creating new things. So you need to be able to do this to classes. You need to be able to get a list of all the classes that are currently defined in the runtime. The Objective-C interface for most of this is defined in Objective-C runtime.h.

So, for instance, getting a list of classes, you use Objective-C get class list. So you can find out what all the classes are. And then you need to construct those shells for the Python objects. You can create new classes in the runtime just on the fly using allocate class pair and register class pair.

So then when it comes time to actually send messages, it's the same kind of idea. You need to be able to grab a message and pick it apart. What's the message exactly? What are its parameters? Where is it going? and then be able to pass it on to something else. The basic mechanism for this is forward invocation. This is the message forwarding system in Cocoa, and it's actually used for lots of stuff, not the least of which is NSProxy, which things like distributed objects are based on. Core Data also uses this kind of technique heavily.

And you can even go one step further in Tiger and actually create method implementations on the fly. There's a library called libffi, it's short for Foreign Function Interface, that lets you construct arbitrary C functions on the fly. They just look like regular C function pointers, you can call them just like anything else. And you can plug those into the object. So you call this method, it just turns into this function call.

And finally, you need to be able to create new messages that, okay, I got this Python thing coming in. I need to turn that into an Objective-C message. There's an Objective-C interface for doing this called NSInvocation. That's kind of a nice high-level version. Or you can go the grungy low-level route with ObjcMessageSend.

So there's some interesting things you're going to run into if you try to do this. One is that Cocoa has a bunch of sort of object machinery that it deals with, which, say, the Python code is not really expected to deal with. This is stuff like message forwarding, so messages like response to selector, key value coding, so you can get things like value for undefined key, key value observation, which bindings is based on, things like will change value for key. So your bridge is going to need to pick these up and handle them appropriately, like there's stuff in the AppleScript bridge to pick up value for undefined key and turn that into an AppleScript property access.

The next thing is that the type information in the runtime may not be enough. The Objective-C runtime has a fairly C-ish view of the runtime system. So, for instance, Boolean. As far as Objective-C is concerned, bool is just a typedef for signed char. It's just another integral type. And that's not good enough for some languages. Like in Ruby, all integers are considered true. There's none of this C, zero is false, everything else is true business.

Fortunately, there's metadata available. There are bridge support files in every system framework that describe full metadata for all the APIs. So you can find out that, oh, this really was a Boolean here. This is an object pointer. What is an object pointer to? You can get an exact type. The Objective-C runtime won't tell you that.

Next up, we talked about forward invocation a little bit. So you can do this dynamically all the time, but that can get slow if you're sending an awful lot of messages. So this is where libffi comes in. If you get a message once, you can do it dynamically the first time, but then construct a real method implementation using libffi. And from that point on, that particular method can be fast. Core Data, I believe, uses this technique now to improve performance.

And finally, this one is a little tricky. Obviously, Cocoa has a whole set of basic types, strings, arrays, that sort of thing. Your scripting language probably has most of these same types. It definitely has a string. And it's kind of nice if NSString turns into just a regular scripting string, so that way the scripting users don't have to think of NSStrings as NSStrings.

What you can do, and this presumes a lot of control over the interpreter, is you can actually build the interpreter on top of foundations. So the scripting string just is an NSString. There's a project called Mac Ruby, you can go check this out on Mac OS Forge, which is doing precisely this with Ruby.

It's basing Ruby on top of foundation. So a Ruby string is an NSString. A Ruby array is an NSArray. It even goes one step further and uses Objective-C messaging for all the Ruby messaging as well. So all the bridging overhead, it just goes away. So it's extremely efficient.

Now, not surprisingly, this is considered an advanced topic. This is not for everybody. That said, it is all public API, and it is all documented. There's no magic secret sauce that only we know. Anyone can do this. And a lot of the bridges are open source, so you can go look at how other people have done this. If you're interested in bridging to some language that isn't on this list, by all means, come and talk to us. We can help out, and we'd just like to know that you exist so we can tell other people about it.

Summing up the whole thing, if you're developing a Mac OS X application, you've got the next killer app, you're just burning to write, write using Cocoa. This is where all of our attention goes. This is where all the good stuff is. This is where you get all the good system services. That said, write the code using the language that works for you. Objective-C, Python, Ruby, it's all good. We are not in the business of dictating what language you should use.

I should actually qualify that. I forgot to do this earlier. I said you can write whatever language works for you. That said, we do still recommend that you learn Objective-C and ideally that you learn it first. There are two big reasons for this. One is that all of the documentation and a lot of the sample code is written in Objective-C and you'd like to be able to read The other reason is a bit more subtle. Cocoa was designed as an Objective-C library. It was not designed as a Python library or a Ruby library or what have you. And therefore, it is following its own conventions. It is not following the languages of your favorite scripting language.

So if you expect it to behave as if it's a native library, you're just kind of setting yourself up for pain. A lot of people can, in fact, learn both of these at the same time. They can pick these apart, keep them separate in their brains. Some people can't. Your mileage may vary. Consider yourself warned.

You can extend your application using scriptable applications. Make other applications do your work for you. Like I said, use Mail to send mail, iPhoto to file pictures, use Excel to create charts for you, et cetera. If your favorite language doesn't bridge to Cocoa, you know, it's not on the system, nobody's written a bridge for us yet, Talk to us.

We may be able to hook you up with someone who is interested. Maybe you can write it yourself. We'd love to have more bridges. We'd love to have more languages supported. Here are the people to talk to. Sal Segoyan is our Product Marketing Manager. John Montbriand is our DTS contact.

Sample code is, or will be, real soon now, I'm told it'll be up by tomorrow morning, available on the developer site. Both the Currency Converter example and the iTunes Web example will be up there. We have lab time on Friday. That's our dedicated lab time from 10:30 to 1:45. Failing that, come find us at various other sessions. We'd be happy to help out. Also, I mentioned the Making Your Applications Scriptable session. That's tomorrow at 2:00.