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-523
$eventId
ID of event: wwdc2008
$eventContentId
ID of session without event part: 523
$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 523] Keeping Use...

WWDC08 • Session 523

Keeping Users Connected with the Instant Message Framework

Integration • 41:37

iChat offers out-of-the-box instant messaging for Mac users, and a rich set of native and scripting APIs for developers to determine online buddy status, initiate chats, and send files through iChat. Find out how your applications can facilitate communication between users by creating workflows with iChat on Mac OS X Leopard.

Speakers: Justin Wood, Matt Jarjoura

Unlisted on Apple Developer site

Downloads from Apple

SD Video (491.2 MB)

Transcript

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

Good afternoon. Welcome to Keeping Users Connected with the Instant Message Framework. My name is Justin Wood, and I'm going to be talking about fostering user interaction with iChat and your application. So to start off, we'll start off with a brief overview of what we're going to cover today.

I'm going to go over what exactly iChat is, and then I'm going to delve right into how you can use the Instant Message API to use all the wealth of information that iChat has about users' presence in your application. We're then going to move on to controlling iChat using the Apple Script API and the scripting bridge that's available. Then we're going to finish up with responding to events that occur in iChat using your application. And to finish, we'll open up to Q&A and hopefully get to some of your questions. Thank you.

So to start off, for those of you new to the platform or not too familiar with iChat, well, what exactly is iChat? A few years ago, this probably required a little bit more explanation, but I think nowadays it's pretty safe to say that iChat is an instant messaging application for OS X. It's actually the native one that we ship with Leopard.

It supports popular instant messaging services such as AOL Instant Messenger, XMPP-compliant Jabber servers such as Google Talk, and Bonjour to keep connected with people on your local area network. I'm sure you've seen lots of screenshots of iChat, but iChat as an application has things like a buddy list, supports text chat, file transfers, audio chat, and a very oft-demoed video chat feature. New in Snow Leopard came things like screen sharing and iChat theater.

Today we're at WWDC, and you guys are probably asking, well, that's great, but what can I do with iChat? Well, we're going to break this down into four main categories of things. First of all, there's presence information. iChat has a bunch of information about people that users have either voluntarily or have been added to their buddy list. You can actually get at this using our native Cocoa API, the Instant Message Framework, and use this in your application to display presence.

You can also get at this information using Apple Script and the Scripting Bridge, but today I'm going to focus on the Instant Message Framework. There's a wealth of documentation about the latter two online. I invite you to check that out. We're then going to move on to controlling iChat from your application using Apple Script and the Scripting Bridge.

Now what this actually means is that your application can kick off events in iChat. You can send text messages, file transfers, start video chat sessions, even start screen sharing with other remote users from your application. We're going to talk about how your application can respond to events that occur in iChat. And what this means is that suppose you have an incoming file transfer. You can wire your application up in such a way that your application will accept the file transfer and then perhaps do something with it when it's actually complete.

The last section of things is iChat Theater. iChat Theater actually is a new feature in Leopard, and it fundamentally is taking a video chat, allowing your application to provide content, video or still, and present it side by side in sort of a neat presentation format with an ongoing video chat. This will actually be the subject of our next session, so I invite you all to stick around and check it out.

So without further ado, let's talk about the Instant Message Framework and presence. Well, what does presence look like, first of all? Well, the iChat buddy list is a pretty good place to start. Along the left side of things, you see the status gems, which are used to represent availability.

You see a list of people, people that the user has actually added to their buddy list. You see on the right side things like buddy pictures and capabilities. Do users have video cameras? Do they have audio microphones? Are they available for video chats at present? So what does a presence look like in another application? Let's try something else we ship, like Address Book.

This is a card view from the standard Address Book on your system, and it has pretty much what you'd expect from a contact application. Things like their name, company information, phone numbers, email, that kind of stuff. In addition, you'll notice here, there's actually an AIM handle. What Address Book is doing is using this AIM handle and the Instant Message Framework to tie this back to a presence in iChat, and if you look carefully, there's a little green status gem, the same one that you see in iChat, right beside the user's buddy picture in Address Book.

Mail is another good example of this. Mail will show the online status of any sender or addressee of a message. You'll notice again it's the same status gem that you see in iChat. Well, how does Mail do this? Well, they've noticed that this email address is tied to an address book card, which in turn is tied back to an IM handle that can be tied to a presence in iChat.

And lastly, a different kind of client. This is actually one of our own. The menu extra, actually, if you look at the bottom, has a list of handles that are available. These are pulled from iChat using the Instant Message Framework. We filter out all the ones that we're not interested in. In this case, we want only available people. We show this as a short list of -- a short way to initiate text chats, video chats, or audio chats with people.

So stepping back just a little bit, what exactly is presence? Well, presence is first and foremost, as I said, the availability of someone in the buddy list. Represent on the left side of things, you have your green gem for available status, you have a yellow gem for idle, and you have a red gem for away. And the lack of a gem represents that person's offline.

There's a bunch of other things that come along with this. We have things like their status messages, their pictures, their capabilities, things fundamental such as, does this user support file transfer? Do they support group chat? Larger things such as, is this person running Leopard so I can screen share with them? Lastly, we're actually going to tie address book cards to people, which will give your application an easier way to call back presences of people you might actually be working with.

So, what does our framework provide? Well, to start off, we provide presence information about the person sitting down at the machine. That is my presence information. This will be things like the availability of the person. What has the user set their own buddy icon? Are they actually even logged into a service immediately? We're going to provide presence information about all the buddies in that user's buddy list.

We're going to provide presence change notifications, so we can actually let your application know when someone moves from available to away, or changes their buddy picture, so you can keep your UI up to date. And speaking of UI, we're actually going to provide to you the status gems that you see on the left side of the buddy list for your use in your application, as we saw here with Mail and previously with Address Book.

So to start at the top of that list, how do we get access to our own presence information? Well, as I said, Instant Message is the framework that you'll be looking at, and the IAMService.h header will have all the functionality that you need to integrate presence into your application. Let's look at a simple call, one called MyStatus.

When you call this, you're actually going to get back a variable type of IAMPersonStatus, which is an enumerated type of any of the availability states, such as available, idle, away, and offline. There's a couple more of these that you'll actually see in the header, And they're well documented there. I invite you to check it out.

So once you have one of these things, how do you actually get the status image to represent a new UI? Well, there's another similarly simple call. Once you have one of these statuses, you can actually call ImageNameForStatus, which is going to return an NSString that you can pass off to AppKit's NSImage API to return an image that you can set on a button cell that you can draw yourself.

So before moving forward, I should probably explain a little bit more about the innards of IAM service and sort of how it works. The class, as we've seen, has a couple utility methods on it and ways to get information about our own presence. However, instances of IAM service are a little bit different.

Each instance of IAM service represents an account type that iChat the application, and thus the Instant Message Framework is capable of talking to. These are things such as AIM, Jabber, and Bonjour, all named services. Each service can have attributes such as, for example, their status. Is this particular service logged in? Are they logged out? A bunch of states that you'd imagine would be in between there.

The service is the actual one that's going through the address book person mapping. So when you have your A/B person object in your application, you can ask a service, "Hey, give me all the handles that I can use for presence lookup on this given service," using these screen names for person call. And conversely, there's a people with screen name if you have a handle that you want to maybe map an A/B person back to. And lastly, and most importantly, we'll get to that, are buddies. Buddies exists on IAM service objects.

How do I get at these IAM services? Well, there's two relatively simple calls. You can just say, hey, give me all the services that iChat currently supports. Or if you know what you're looking for, you can address one specifically with a name. Now it looks something like this.

An important thing to mention here is that as of Leopard, we supported multiple logins to any given service. Now what this means is that you can have two AIM accounts or more logged into the AOElements Instant Messenger service simultaneously. Same for Jabber, and Bonjour still only allows one, because it would make much sense otherwise. In this example, you see here two Jabber, two AIM, and a single Bonjour list. And it's important to note that this does not represent five IAM services. This still represents three.

The buddies, the status information, is all going to be sort of a best-case scenario in a mix of all the buddies and the best status of a given service. So if one of these accounts were logged out and you asked for the services status, you'd probably still get logged in, given that one is still there.

So buddy information. Buddy information, once you have one of these IAM services, is relatively easy to get at. There's two ways to do this. You ask for the info for a particular screen name if you know who you're looking for. Or you can ask for the entire buddy list with info for all screen names.

The information is returned to you in the form of a dictionary, a dictionary which contains a variety of keys and values, all of which are listed in the actual header and explained there. But they'll have things, for example, like the person's screen name with I am person screen name key, their status, status key, and so forth. So let's walk through a brief example of how this would actually work.

So let's say we're talking about AIM, and we're looking for an AIM buddy in our application. So first order of business is let's find a reference to the AIM service. So we ask IAM service for the service with name AIM. Given that reference, we can then ask for information about a particular screen name, which will give us back a dictionary if that person is in the buddy list.

From that dictionary, we can start pulling out the statuses that are interesting to us. Things like, given that we know their screen name already, might be nice to show their status and their status message in the UI, and maybe a little picture on the side. And, you know, we can also show their first name for a little bit of a cleaner user experience.

That's all you pretty much need to integrate presence as it exists in your application. Now, iChat has this ever-evolving or ever-changing presence concept that people go from available to away fairly often. So your application needs to keep up with this. And to do that, we have presence change notifications.

These are given to you with a custom NS Notification Center. For those of you unfamiliar with NS Notification Center, this is a standard foundation-level object that, for all intents and purposes, you can register with to say, hey, I want to know about certain events or notifications occurring. Example ones are IAM Service Status Change Notification, where you can imagine this will let you know when a service, say AIM or Jabber, moves from logged in to logged out.

If you want to know when someone changes their status from available to away, you can register for the IAM Person Status Change Notification, which will let you know when that happens. Similarly, if your application shows buddy UI, such as their picture, you can register for the IAM Person Info Change Notification, which will let you know when any of the vast number of presence keys out there actually change.

Each of these notifications comes with a bit of context information, and this actually is delivered by way of the user info. This dictionary contains the same keys that you saw on the previous slide to look up buddy information, so it should be pretty straightforward to see there. So let's look through a sequence of events that an application might do to support these things. First of all, we need to get our application to register for these notification changes, which would look something like this.

We ask the IAM service for its notification center, add ourself in this case as an observer to the IAM Person Status Change notification. And notice that we're having it call us back on the Person Status Change method. Next step, we need to get notified. And to do that, well, someone needs to change their status, and on top of that, we need to actually create the method to handle the net status change. So that would look something like this.

Here we have person status changed, and the first order of business is to pull the user info dictionary out of there. We need to know whose status actually changed, so we're going to ask that dictionary, hey, I need the value for the IAM person screen name key. So that's immediately going to tell us who we're talking about here.

And given this is a status change, we're probably interested in their new status. So in turn, we can pull the new status right out of that dictionary. For the purposes of this example, we're actually just logging this out. But as you can imagine, your application will put in the glue code that it needs here to update its views, models, controllers, do all the bookkeeping that you need to do.

After that, well, that's pretty much it. You're fully tied into iChat. You'll receive notifications for any time any presence changes in the UI. So side by side, your application will keep up to the goings-on of things. There's one important detail here to note, is that presence will be pushed to you as soon as you register with this notification center. Now simply put, this means if in my previous example, I was interested in the IAM Person Status Change notifications. As soon as I register for these, I am immediately going to be pushed a presence change notification for everybody that iChat has, with their current status.

So what this means is that your application doesn't actually need to ask for the initial status of things. You don't need to do that startup and build your initial map of, you know, the state of the world. You just simply need to register for your notifications, and then the same code that does your UI update and your model update will actually build your sort of initial state of iChat. And this will work whether iChat is currently running or not. If it's running, you'll expect a bunch of these things to come in. If it's not, then, well, when iChat pops up, your application will be ready to go.

So let's walk through a brief demo of this. I'm going to show you some sample code that's actually available online, and I'm going to walk you through the glue code that basically ties IAM service to our simple data model. This application is simply looking through the address book, finding every A/B person, and just trying to tie a presence to them. So let's take a look.

So here online, I'm going to open up the AB Presence project, and I'll give you a little overview of how this thing works. If we look at the standard main menu nib, is the interface builder here. This is just a simple window that's going to have a list with two columns. There's going to be some text and an image along the side here.

In the actual Nib, we have two objects declared. We have a Service Watcher and we have a People Data Source. The Service Watcher is going to be the class that actually ties IAM service to the data source. So, let's start with Service Watcher. Pretty straightforward class, no I of Rs, and it just has two simple accessors, Start and Stop Monitoring IAM Service.

When it loads up from Nib, it's just going to tell itself to start monitoring. And the monitoring, as we saw previously, is very straightforward. We pull the IAM Services NS Notification Center, and we start adding ourselves for interesting notifications. In this case, since we're going to be looking for both presence changes and status changes, we register for the IAM Person Status Change Notification here, and the IAM Person Info Notification changed here. This notification at the top is actually the one I was talking about for the IAM Service Status Change Notifications, but this application doesn't need to do anything with them.

So, let's take a brief look at these. As I said, the service status change notification, we're not really doing anything with, but the person status change notification is where everything happens. What we're going to do is pull the service that this notification is talking about. So when someone on, say, our aim buddy list has gone from available to away, we're going to pull the service to figure out the service we're talking about. I'm going to pull the user info out, I'm going to pull the screen name out, and then I'm going to use that service that I grabbed to find all the address book people that could potentially be associated with the screen name.

My data source, as I mentioned, is a list of people in the address book. So I'm then actually going to list through all the address book people that could be affected and post a little internal notification-- this is how one is talking to the other-- of, hey, these people, all these address book people might have changed. You should probably reassess your state of affairs.

So moving on to the People Data Source. If we look at this guy, it's pretty straightforward as well. He has two parallel arrays. Not exactly the most efficient way to go about it, but it gets the job done. We have a list of A/B people in our address book, and we're gonna have a parallel array of IAM person statuses. These will just be NS values that map back to the enumerated type that I talked about previously. We also have a reference to the table.

So, if we look at the initial startup of this thing, or... Here. The general sort of brute force way to go about rebuilding status information for all your buddies here is, first of all, clear out this parallel array, go through all the people in our address book list, And this is a little bit confusing here, so I'm going to walk through it a little bit slowly.

We're going to start with a-- What we're trying to do here is to find the best status for all the available handles for this given A/B person. A person can just have one, or they can have as many as you have assigned. So we're going to start with offline as our best status. We're going to iterate through all the services that are available to iChat.

We're going to ask all those services, hey, what are the screen names that you support? So if someone just has an AIM handle, this is going to iterate through a few times. But it's only going to find one AIM handle and do all this code for that. It'll ignore Jabber and Bonjour, for example.

So once we have these screen names, we're going to iterate through the screen names and ask that service for all the information it has about that screen name. That'll give us back a dictionary that we're going to then pull the status right out of. If we have a status, we're just going to cast it to an IAM person status, and then compare them.

This is another utility method you'll see in IAMService.h. It's just a simple comparator to say, is available better than away, because they're not necessarily ordered as you might expect in the header. If it's a better status, we'll remember this and move along. Once we're done with a given person, we note the best status that we found and tell the table to reload its data. Fairly straightforward.

So that notification that the service watcher previously would post will just kick off a reload table, or a reload AB people for this data source, which will just go back through and note, basically note changes that's happened to people and update the UI. So let's see this thing working. iChat.

I run this, and you can see the application just popped up immediately. I do have iChat running in the background. And it showed here, hey, this guy's idle, this guy's away. And this machine hasn't been touched for a little while, so I'll just move the mouse. And look, Jane McDouglas has now become available. And that's it for this presentation. So, if I can go back to slides.

So in summary, instant message is the way to get presence in your application. It's a very simple Cocoa API, and it's a very simple usage pattern. All you have to do is register for presence changes and handle the changes when they come in. There's no need to pull for initial state. That's it. Very small amount of code that you'll need to write.

Going back to what Bertrand said in the State of the Union on Monday, if you happen to be there, this is Snow Leopard, and we really are looking for your feedback. So I invite you all to check out our sample code, look through the instant message documentation, and think about, can I use this in my application? Do you use AB People anywhere in your app? Does your application revolve around dealing with people? Is it a contact managing application? That sort of thing. If the answer is yes to any of those, then chances are you're a pretty good candidate.

So check out the source code, register for the status change in your application, and see if you can get to the point where you have a green gem showing up somewhere useful in your UI to the user, maybe next to their name, their picture, as you saw in Mail or Address Book.

We have a lab tomorrow morning, bright and early, 9:00 AM. So I invite you all to come there and let us know how it went. I'll be there myself, and fellow iChat guys will be there looking forward to it and looking forward to helping you out get this thing working. And with that, I'm actually going to introduce the next person. Matthew Jarjoura will be talking about controlling iChat using Apple Scripts and the Scripting Bridge API. Thank you.

Thank you, Justin. Hi, I'm Matt Jarjoura, and I am an engineer on the iChat team. And today I'm going to be talking to you about controlling iChat using Apple Script and the Scripting Bridge Framework. So I'm going to be talking a little bit about what is Apple Script, and then I'm going to give you some examples of what you can do with Apple Script in iChat, and then I'm going to talk to you a little bit about a new framework we added in Leopard, the Scripting Bridge Framework.

So for those of you new to the platform or just unfamiliar with Apple Script in general, you may be wondering what exactly Apple Script is. How does this thing work? AppleScript is actually defined as an English-like language. For instance, here it says, "Tell application iChat, "Display dialogue, hello," which then gets converted into an Apple event, which is this message that then gets passed on to an application, such as iChat in this case, is its dialogue message.

So with AppleScript, you can write shell scripts just like you can with Perl, Python, Ruby. There's a command line utility OSA script that lets you run these tools. And you can control a specific application with AppleScript. And you can also respond to events. Say, for instance, you get a mail message from a group list, and you want to process this with more than just, say, maybe make a sound or move to a folder, you can attach an AppleScript to that.

Okay, but today we're here for iChat and what you can do with iChat and Apple Script. So the first thing is you need to set up your Apple Script code. And of course, with any language, you need to set up your block. And the first thing is tell application iChat. And anything inside of here, then, you can use to control iChat. So let's go ahead and get to our first example, starting a new text chat.

Okay, so to start a new text chat, you need to create a new text chat object. And to do this, I've highlighted a line of code here, "Make new text chat with properties." And what this is going to do is this is going to create a new text chat object, and then we're going to fill it with the properties participants, which is basically I'm building a dictionary here, so participants is the key. And then I'm filling it with a signed-on buddy smarter child.

So then I'm passing the participants into the properties that's creating the new text chat, and then I'm setting the result of that to the text chat object. So once you do that, iChat will open up the window to that person, and then you can begin sending actions to it. Say, for instance, send hello to the text chat.

Okay, how about starting an audio conference? Same thing as before, only this time make new audio chat. Again, you pass in the participants, in this case, Jane McDouglas. She's a signed-on buddy. And then when you set the result of this to my audio conference, now the difference is actually as soon as you set this, you're actually going to initiate an audio invitation to Jane McDouglas. So just be aware if you're running through and testing it out and all of a sudden Jane's talking to you out of the blue. Just be aware. Okay, how about a multi-way video conference? iChat.

Same thing here, make new video chat with properties. Only this time I wanted to highlight here the participants. And notice this time now we're actually having multiple participants. Here we have Buddy, Jay McDouglas, Mark Hammond, Kelly Adams here. So when we pass them in, you're actually going to be passing in an array of participants that will go into your new video chat object. And again, just like the audio conference, as soon as you set your video conference, or my video conference there, It will begin and all three people will be invited.

Okay, how about joining a chat room? Now this one's a little different because here you actually need to be very specific about the service you want to connect to, because each service that you're on could have a different conference that you're joining. You know, say Google Chat is not going to have the same conferences that AIM is going to have.

And unlike the Instant Messaging Framework where you're specific with just AIM Jabber, you're actually going to go and get the specific service itself. So here in this example, I'm saying the first service whose service type is AIM. All this is really saying is of all the services that I'm connected to that are AIM, get me the first at index zero of this array. And then set the result of that to the service. And then we can use it here, just like before, make new text chat with properties. I'm going to say join name iChat WWDC, and then set the service there.

Now, with iChat, it's not actually going to bring up a window until you're officially in the channel, so it may take one or two seconds before the window pops up. But as soon as the window's up, then you can begin sending actions to it again here. Send hello room to WWDC room.

So where do you go from here? Of course, these are just a couple examples that I wanted to show you. But the cool thing about Apple Script is it's the Script Editor program that you see here. It's installed on everyone's copy of Mac OS X. So you can just bring it up. It's in your Applications/AppleScript folder.

And when you go to Script Editor, you can bring up an application's dictionary. Essentially, this is its API. So here, if you pull up iChat's dictionary, you can see things like everything that you can do with it using Apple Script. Log in, log out, take a snapshot, and then the same objects that I was creating before.

A text chat, audio chat, video chat, etc. So go ahead and check this out. There's also documentation you can view. It'll give you, basically explain what you need to do to pass what properties you need, and things like that. Okay, now let's move on to the scripting bridge framework.

So how does the scripting bridge framework play into this? So previous to Leopard, if you wanted to do anything with AppleScript, you actually had to instantiate an NSAppleScript object. Some of you may be familiar with this. And pass in a small snippet of code into this, which then went through AppleScript to actually process this. When Leopard, they added this scripting bridge framework, which basically bypasses this now. So it itself is directly going to Apple Events, so you don't have the overhead of AppleScript anymore.

So the great thing about ScriptingBridge is actually it's built on top of Objective-C, so you can control your application, control iChat with Objective-C. And since Leopard now that other scripting languages have first-party supports, Ruby, Python, Perl, you can also use those to control an application as well. And all the interfaces are generated dynamically, so all commands, except handlers, which we'll get to later, are made available to you. And this works with any scriptable application, Mail, iCal, iTunes, even yours.

So where to start with the scripting bridge framework? Well, if you run this command line utility here, you don't even have to worry about copying that down. It's listed on developer.apple.com. And you can type in man sdp. It'll walk you through. But the idea is by running this command line statement here, you'll actually be generating yourself a header file, which will be the same content that you saw in the dictionary in the scripting editor. So this will allow you to see it in, basically, hopefully, your favorite format, Objective-C.

But the thing is, there's no accompanying .m file, so to actually use the scripting bridge, you're going to be doing this all on runtime. And here we have the class method application with bundle identifier, and you pass in the bundle identifier, com.apple.ichat, and then it will generate the class and instantiate it iChat app. And then iChat app, you can, say, pass an Objective-C 2.0 property status message. And as soon as you set this, it should be reflected in iChat. Pretty straightforward, I think. OK, so let's walk on to some examples now. The first one, sending a file.

So to send a file, you want to create an NSURL reference of your file, in this case, Here I'm doing Grand Canyon, which is basically just a folder of pictures. And in this folder, basically, I'm going to-- and then I need to get my buddy. So I'm going and getting a buddy that's already signed in, in this case, Jane McDouglas.

So I'm going to iChat app, getting the list of buddies, and then saying, OK, well, which one's signed in? Jay McDouglas. And then I'm going to go ahead and pass the file URL to iChat with the buddy. And this way, iChat will take the file URL and send her the file.

Okay, how about starting a new chat? Now, because this is generated dynamically, you're actually going to have to go back to the scripting bridge and say, I actually want an Objective-C class for this scripting class, TextChat. And once you have this class, then you can actually create your object.

So, you take your dictionary, just as we did before, and you pass in Smarter Child as assigned in Buddy to the participants, and then you pass that into your new TextChat object. And unlike AppleScript here, you actually have to tell iChat that you want to add this to its list of text objects. So, as soon as you do that, then the window will open up, and then you can begin sending messages to Smarter Child.

Hey, how about joining a chat room? Just like before, you need to actually get the service of the chat room you want to sign into. Here in this example, I'm just getting, of all the services that I'm on, I'm just getting the last one. And then here, I'm passing this into the dictionary.

So I'm saying, with this service and this chat room name, iChat WWDC. And then basically I'm adding the object to its list of text chats, and then again, wait one or two seconds, hopefully no more than that, and then the chat window should open up. Okay. Let me go ahead and walk you through a little demo here.

Okay, so I'm actually using Ruby Cocoa here. Some of you may be familiar with this. But, so what I have right now is just a simple little wrapper around Xcode build. What I wanted to do is come up with a little build script that I can use to just try to cut down on the amount of repetition that I'm doing here. So I basically collapsed it up. It's not really, it's just basically a simple wrapper on Xcode build. But the most important part I wanted to show you here was that I've created my builder object.

And that I basically executed the build for a debug build phase and then a result, I mean a release build here. And then basically each time I'm printing to the command line, here's my status. And then I'm printing to the command line. So if it's not successful, then fail. Otherwise, print out that it was successful. So here we can say, Builder Step 1, and run that, and then it'll go ahead and just compile the app.

If you caught that, it actually said build a successful Well, we want to make this a little bit more interesting. Of course, you're here for iChat. So what I did is I went back and I said it would be really cool if I could have a status posted in a chat room.

So if everyone that's working on my team could sit in the chat room and actually see the result of this build. So what I did here is I went back and added Ruby Cocoa to this project. So in require OSX slash Cocoa and then include OSX. This basically brings Ruby Cocoa into the project. And now I'm going to require the framework scripting bridge. So all I did here is I added another simple class which just wraps around, again, the scripting bridge APIs and iChat APIs to try to make it even easier to basically set up a little bot.

And again, here you see dictionary with objects and keys. And I'm passing in just the first service that I'm signed on to. And then passing it in a room that when I create my bot, I'm basically assigning the room at that point. And then I'm adding it to iChat's text chats.

And then I just created a simple method to send message to this chat room. OK. So here we are again at the code that you saw in the previous example. Only this time now, I've added a global bot object, and then I've replaced each of my print to the command line. But now this time, I'm actually going to be sending the status to a chat room. Okay, so let's see here. I am in the chat room now. I'm going to go ahead and run this example.

Back to the slides. Okay, so there's actually online documentation that can tell you how to integrate just dragging in a .application file into Xcode. You can check that out. That's pretty cool. So you don't have to type in the command line every time you want a header file. But it's easy enough. You can add the framework to any of your applications and begin using the scripting bridge today. And if you're curious, there's another session. Actually, it's today at 5, 5.25, Cocoa Development Using Scripting, if you're interested in more information about this.

Okay, so we move on to the next part now, which is actually responding to events. And unfortunately, this only applies to AppleScript. But I wanted to walk you through kind of what exactly that means, responding to events. Well, if you go to the Alerts Pref pane in iChat, you can go and set up an event for any number of the events that we have here. When I log in, when I log out, say a buddy becomes available, message received in this case, and you can attach an AppleScript handler to that event.

So whenever that event occurs, basically what iChat will do is go off and fire that handler. And of course, we provide a handler for every one of these events. AVChat started, invitation to share my screen, incoming file transfer, and we're going to pass all the relevant objects to that method so that you can use it. Say, for instance, you get a message, you actually probably want to have the message there for you. So we'll hand that off to the handler.

And here's just a simple example. Instead of saying tell application, this time you're actually going to say using terms from application. And then you're going to have inside of it onMessageReceived. And this is the same thing that you would think of like a method onMessageReceived. And then the variables, the text, the buddy, the chat. And the little bits, the from here and the for, these are actually just required bits.

It makes it a little easier to read, of course, but to get these bits, to make sure you're putting the right ones in there, you can go back and check the iChat dictionary. It'll tell you what you need to have there. And of course, inside of this block of code, then it's set buddy name to get the name of the buddy, then display dialog. Pretty straightforward there.

Okay, so I'm going to walk you through more demo. So I thought, wouldn't it be really cool if I could do the same thing, starting to build, but if I could do it from inside the chat room that I'm in right now? So I added a third step here.

And again, now I thought, what would be the best way to approach this? And I said, well, I'm going to go ahead and use this mongrel HTTP server. And some of you who have used Ruby on Rails might be familiar with this. It's just a simple little HTTP server. So I've added this into my project. And the only thing I've added here is now every time I get a URL to start, I'm going to go ahead and process this method.

So all I've done is moved the same code that was in the previous example into this block here that allows me to run every time I get a URL start. So I can actually keep this running and then start the build multiple times. But without having to worry about adding a queue or anything like that, just for simplicity's sake today, basically I just set up a little flag that says, if I'm already building, go ahead and get out.

But certainly, if you wanted this a little bit more robust, you'd probably want to have a queue that says, all right, I'm going to build up a queue every time someone makes a start request. Okay, so then you're going to actually hook up the other part of this, the message received part of it. This is the part that actually your users are going to have to do.

They will attach this little bit of code. So on Chat Room Received, again, the message, the buddy, the chat, and then so I'm going to test to say if the message is Start Build, I'm going to fire off curl, run this shell script curl, basically starting the build. So then I'm going to go to iChat now.

And I'm going to go to Chatroom Message Received, and then I'm going to choose a script. Okay, so now whenever I receive a message, it's actually going to go to this script. Let's see here. Start. Oh, I'm going to run this, actually. All right, so again, it brings it back here. And then start build.

Back to the slides. All right. So in summary, basically we have this Instant Message Framework again, so if you want to incorporate status in your application, and just like address book or mail, if you think your application fits this kind of application, then we have this Instant Message Framework to show you status perfect. And if you want to add notifications to your application in Apple Script, for instance-- or you can use Apple Script in this case.

And if you have any more feedback from today or any questions, Matt Drance, he's our sharing technologies evangelist. You can send him an email. Again, you can check out the attendee site. I believe that there's sample code for this session posted on there for today. And we certainly encourage all of you to join our mailing list, iChat Dev. There's engineers from Apple on there who can help you if you have any questions or concerns. And you might want to stick around. iChat Theater we're going to talk about next.

And there's an iChat lab tomorrow morning at 9 a.m. All of us will be there to answer any questions again that you might have or comments, take any feedback. And then on Friday morning, there's actually, if you're interested in more scripting bridge, Apple Script Talks, there is an application scripting automation lab.