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: wwdc2007-204
$eventId
ID of event: wwdc2007
$eventContentId
ID of session without event part: 204
$eventShortId
Shortened ID of event: wwdc07
$year
Year of session: 2007
$extension
Extension of original filename: mov
$filenameAlmostEvery
Filename from "(Almost) Every..." gist: ...

WWDC07 • Session 204

Fostering User Interaction with iChat

Leopard Innovations • 51:10

Make your users more productive by embracing instant messaging technologies in your application. Learn how to display and track buddy information inside your application using the Instant Message framework. Become part of a user's daily workflow by initiating file transfers, AV chats, and more with iChat's newly enhanced scriptability. Leopard's Scripting Bridge even allows you to control iChat from your own Objective-C code. Come and see how iChat support can add a whole new dimension to your application.

Speakers: Jamie Montgomerie, Eric St. Onge

Unlisted on Apple Developer site

Transcript

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

Welcome to session number 204. This is Fostering User Interaction with iChat. I'm Jamie Montgomerie. I'm one of the engineers on the iChat team. So the agenda for the session. First we'll talk a little about what iChat is, iChat 101. If you're not familiar with iChat or all of iChat this should get you up to speed. Then we'll talk about observing changes in iChat using the Instant Message Framework, how you can look for changes in iChat and react to them in your application.

Then we'll talk about controlling iChat using the AppleScript API and the Scripting Bridge, which is a new technology in Leopard. The Scripting Bridge lets you use the AppleScript API from your language of choice. We'll talk about Objective-C. And then we'll have questions and answers at the end. So, iChat 101. What is iChat? Well, here it is. I'm sure we'll see you're familiar with it. iChat is Mac OS X's built-in Instant Messaging client. It works with AIM, which is AOL's instant messaging protocol.

Actually all .Mac users have an AIM handle. They can use their @Mac.com address to interact with AIM users and each other on the AIM network. We also support Bonjour, which allows you to instant message with people on your local subnet and we support Jabber, which is more formally known as XMPP. It's an open standard. It's getting used by more and more people now. The largest or the highest visibility client is probably Google Talk.

They use Jabber for all their communication and iChat can talk to Google Talk through Jabber. So you can talk to all your Gmail friends. It's also used by, I think, by Live Journal Talk and I think Gizmo uses it for their instant messaging. You can also use Jabber in your organization, that is, if you buy Mac OS X's server it comes with iChat server, which is a Jabber server. So you can use that to do instant messaging inside your enterprise or your small business. It works pretty well.

So what does iChat actually do? Well, it provides you with a list of buddies. Generally these are, the user sets them up for people they know so they can communicate with them. You can text chat to your buddies. You can transfer files to them. They can send files to you.

You can do audio and video chat, as I'm sure you know, as an example. And new in Leopard you can share your buddy's screen, your buddy can share your screen. This is great for collaboration or for helping people out with stuff. And, of course, iChat Theater, which lets your send your applications content over the iChat connection in a sort of show-and-tell type model.

So what can you do with iChat? Well, the Instant Message Framework, which is part of Leopard and actually also in Tiger, although it's expanded in Leopard, allows you to get presence information and display a new application. It also allows you to control iChat Theater. iChat Theater, I'm afraid we're not going to talk about today. That's session number 202. We'll go into all about iChat Theater and how you can use it.

It's tomorrow at 2:00PM. I think in Presidio. So if you want to know about iChat Theater you should definitely come along to that. It should be an exciting presentation. So for today, the Instant Message Framework, it lets you get presence information and display it in your app and that's what we'll be talking about today.

If you want to do any of the other things that iChat does, actually the highlights are all in this slide. All the white things here, you can do all of them through AppleScript and using the Scripting Bridge you can actually do them using Objective-C or Ruby or Python. So this lets you control iChat to do what you want via your application.

So first thing we're going to talk about more in depth, observing changes in iChat using the Instant Message Framework. So the Instant Message Framework provides presence information to your application. And we actually use it a lot inside Apple. So here's our presence information in the buddy list, natively in iChat.

We use it in mail. You can see that Eric has a little gem next to his name here showing that he's online. That's using Instant Message Framework to get that information. Similarly in Address Book, the little gem next to Eric, Eric's picture here. It's using the same mechanism. And actually a lot of people don't realize but the iChat menu extra, all the information that's displayed here actually comes to the menu extra through the Instant Message Framework too. So you can get all that information and use it in your application. It's not just part of iChat.

And some people already do. Project X and OmniPlan use the Instant Message Framework to get presence information in their application and the next version of Delicious Library will also be using it. And scripting visual iChat, which we'll talk about a little later on. So presence, I'm talking about presence, it's kind of a weird term. This is what presence means to us.

So presence is the availability of someone in your buddy list. So you see highlighted are the gems on the left-hand column here. The people at the top with the green gems, they're available to chat. I think you can see Pierre here is idle. He's been idle for 40 minutes.

He has the yellow gem. That means he's probably somewhere near his computer. He's marked himself as available but he hasn't been using his computer for a long time. So we don't know if he's really available or not. Bruce has got the red gem. That means that he is away.

His computer is running. It's running iChat but he's marked himself as away so either he's busy or he's gone for lunch or something. You probably don't want to send him a message or at least if you do send him a message, probably he's not going to reply immediately.

And new in Leopard is this sort of gray gem, which is next to Eric's cell phone here. That means that we can send this buddy a message, and we should be able to send it to him immediately but he might not get it immediately. They might not be able to react to it. Generally the gray gem means that someone's on a mobile device so we can't really see anything about whether they're available or away or not. But we know they're there, that we can send a message to them.

Also counted as part of presence are the status messages. People can set their own message, tell you a little bit more than just they're available or away. You see that Mike is performing some research. Justin's pretty exhausted and Bruce has set himself as being away. The picture, people can also change the picture, little icon down there, right-hand side. That is the icon that people have set for themselves, and sometimes it's a picture of them and sometimes it's just something they're interested in or thought was cool.

Capabilities, this kind of corresponds to the column I've got highlighted here. So this'll say whether you're capable of video chat, whether you're capable of multi-way video chat, audio chat, multi-way audio chat. And also things that aren't showing here like iChat Theater, file sending. You can get that through the Instant Message Framework and tell whether people are capable of that or not.

I also, we also use the Address Book card, which kind of, we think of kind of associated with presence. Everybody on the list here you'll see that we're displaying their full names. Those are not actually stored. They're not actually given to us by the AIM protocol. We just get the handle that you see here on the Address Book card, a fake screen name being Eric's handle, not actually his real handle.

And we use the Address Book card to associate the handle with the full name and you should be able to do the same. So delving into the API a little more. The IMService class is basically how you interact with the API There are some class methods on it, which will provide you with the current user's presence information, which corresponds to what they've set for themselves.

The IMService instances, these'll be one per service. I'll talk a little bit later about what a service is. But it'll give you presence information per buddy. So you can get presence information, ask for the availability or the status message of icons for each of the buddies on the list.

You can get IMService notifications when any information changes. These are Cocoa notifications. If you're not familiar with them basically they're just, you sign up for them and you get a callback whenever anything happens. You can get IMService notifications whenever any of the information that's displayed in the buddy list here changes.

And there are also named status images. So you can ask the Instant Message Framework for the images. You'll get the same images as are shown in the iChat UI. So you can be sure that you'll be consistent with iChat. And it's important to use this because actually there's a preference in iChat, which you can set it to show shapes instead of gems, useful for color blind users. So if you want to be like iChat and show consistently what's in iChat API, use these images and you'll be set.

So I'll set them back to normal. IMService class methods. I told you that these provide information about the current user. You can ask for the user status, basically what they've set their status to is in the pull-down there. You can ask for their idle time. We don't actually show this in the iChat API. This is, I'm sorry, we don't actually show this in iChat UI. This is how long the user has not been using their computer for. Yeah. As I said, we don't show it but if it's important to you you can ask for it.

You can ask for all services. So I said before I would delve into what a service was. These might be logged into AIM. The AIM buddy list here. May also be logged into a Jabber server. They could be logged into Bonjour. They might, even Leopard, be logged into more than one AIM account. They could be logged into more than one Jabber account if they're Google Talk and also in their Enterprise Jabber server.

But they'll always only be three services. They'll be one Jabber service, one AIM service, and one Bonjour service, or at most three. If they're not logged in they won't be available to you. So all the Jabber buddy lists are grouped into one Jabber service. All the AIM buddy lists grouped into one AIM service and the Bonjour service, of course, is only one list. It's one service.

For notifications, there's a NotificationCenter provided as a class method on the IMService class. This is the NotificationCenter that all notifications to do with instant messaging will be sent from. So if you're signing up for notification remember to use this NotificationCenter, not the default one. This is the one we always use. And you get notifications, for example, when someone logs out like that.

The IMService instance methods. Remember I said these correspond to getting information for each of the buddies on the list. There's one of these per service. As I said before you get them in API in the last slide. You can ask for the localizedName. If you're going to show the name of the service in your UI you should definitely use these. For example, you get AIM back for this service. It could be different in different languages.

You can ask for the status. This'll give you the most available status for any of the buddy lists on the service. So, say, Joe had logged out his .Mac service, he'd set it to offline. You'd still get available back because the AIM buddy list is available and you're asking for the status of the AIM service.

You can ask for infoForAllScreenNames. This will give you back an array of information and with one item correspond to every individual buddy and all the buddy lists of the service. And you can, kind of in reverse, ask for the screen names for an Address Book person. If you already have an Address Book card or you've got an Address Book card somehow, maybe using the instant message API or maybe some other API, you could ask the service if there are any screen names which will be compatible on that service. So you would get Eric's fake screen name back this way.

So the notifications that IM service sends. This is how you find out if anything in the iChat UI is changing and you can react to it in your application. Notifications that are available to you are the IMServiceStatusChangedNotification. You'll get this notification whenever the service status changes. So if Joe changes his status to in a meeting you'd get back a notification that he'd gone away.

The IMPersonStatusChangedNotification. So if you watch Eric, if he goes away you would get a similarly, you'd get a notification telling you that Eric had gone away and set his local user. There's the IMPersonInfoChangedNotification. So the previous two notifications will only give you information about their status, like whether they're away, available, idle.

The PersonInfoChangedNotification, you should listen for this if you're interested in any of the finer grained information. Like, for example, if Eric changes his buddy picture you would get this PersonInfoChangedNotification and then you could requery to get the new buddy picture to show in your UI. On the all return userInfo dictionary there's various keys. You can look in the header, I think they're fairly self explanatory.

These one's, for example, the PersonScreenNameKey and the PersonStatusKey correspond to the screen name of the person so you could find out who the notification is for, they're status, if they're status has changed, this is what you'd want, the key you'd want to look at to find out what their new status is. So having seen the API we'll give a little demo. Starting on demo machine B. So we've got Joe's AIM buddy list here.

So we have a demo called ABPresence. This is just a simple example. It basically will show everybody in the Address Book. So I show the Address Book here. Got a bunch of people. And it'll show them and query their status from iChat and it'll also get notifications when their status changes. So here if we look, if we had more than one buddy list this would show the information from all the buddy lists.

We can look, you can see the gems here correspond to the status of the people in iChat. If Eric goes offline, Eric is listed as Steve Chatter here on the second demo machine. You can see the gem changes reacting to the change from iChat. Now if Eric comes back online, if AIM responds. There we go. Eric's back online. Now he's away. Now he's available again.

So if you want to show status like this in your application, you want to know how it works. So here we've got some classes here. The ServiceWatcher class. It's the class we have that's listening to the notifications from iChat, so you'll notice when we start up When we awakeFromNib we'll start monitoring. And when we start monitoring all we do is listen for the IMPersonStatusChangedNotification, which will tell us when any of our buddies change. And we also listen for the IMStatusImagesChanged AppearanceNotification, that enables us to update our UI if the user changes their status image presence.

So what do we do when we get these notifications? Well, in this method here, we take a look at it. When we receive this notification, it's pretty simple. All we do is we get the IMService, which is the object the notification was sent from. We get the userInfo dictionary from the notification.

And we also, we ask inside the userInfo dictionary we get the screenName, which tells us the person that this notification was for. And then we will look up, by asking the IMService, for people with the screenName that we just got back and for an array of Address Book people.

And we get an array because potentially more than one Address Book person could have the same IM handle in their Address Book card, which would be kind of weird but it's supported so we have to look for it. So we look through all the Address Book people that we have, got information back for, and they'll post this notification, which is, this is internal to our application. This notification is sent and our UI class will list that and update itself.

And we're sending it from the Address Book card. And similarly when we get the IMStatusImagesChanged AppearanceNotification we'll post off this internal notification to our UI class telling it that it needs to refresh itself. So if we look at our UI class, we've got that in the PeopleDataSource. And the table here is just a standard Cocoa tableView, so PeopleDataSource is a tableView data source.

If we look at what it does, when it awakes from nib it's actually also registering for AddressBook changes. If you want to know more about that you can look at the code. The two we're interested in the AddressBookPersonStatusChanged, this is the one we're sending from our class that's watching iChat and also the Status ImagesChanged that we're sending our class list watching iChat. So if we look at the method recall, we're simply rebuilding StatusInformationForPerson. That's an internal method. If you look at what it does, all this code, by the way, is available to you. It's attached to this session, if you want to download it and take a look.

It's a little complicated. When I go through it you'll see why. So we get this abPeople is an instance method that's holding all the Address Book people we know about. So we look through each of them. If the person is the person that we got the notification about, well, first say they're offline. Then we will look through all the IMServices that iChat can tell us about.

We'll try to see if the person the IMService corresponds to one of the people in the Address Book cards, this for loop is looking through all the screenNames that this person has on his service. And then we will look at the, get the information for the screenName that we're looking for.

We'll look up the status inside the dictionary we get back, using the PersonStatusKey to get that information. Then if we get some status back we'll get the integer value of it and we'll IMComparePersonStatus, which is an instant message function. It will tell you the best status out of the two, so the most available. If it's more available than the one we knew about it'll store the one that we just got. And then we will call this internal method to store it away so we can update our UI with it.

The reason we're going through all the different services and looking for all the address cards is because an Address Book card might have more than one, more than one instant message handle in it, perhaps more than one service and we want our UI to display the most available ones.

So if the user had a Jabber card, a Jabber handle in their Address Book card and they also had an AIM handle in their Address Book card and they went offline in AIM, we wouldn't want to mark them offline. We'd still want them to available because we can talk to them through Jabber. So after we're done this we simply reload the data in the table and it will call our callbacks to get the information back. So if you look at the callbacks, this is the tableView data source callback.

It's very simple in contrast. All we do is look at which column it's for, if it's the image column we'll ask the IMService for the appropriate image, as I show in the slides, for the status and we'll just return it. It'll, the tableView will show it for us.

And if it's the name column, we just ask the address book card for the display name and we return that. And the only other notification we're looking for is the statusImagesChanged notification. In this case all we need to do is reload the table data because, as we saw, every time the table redraws it will requery the Instant Message Framework to get the appropriate artwork. So if we show that working, go in to iChat.

If we search to Use shapes to indicate status, if you watch the shapes on the side you'll notice people will update. So everything's working great. Ok, so that's it. I say, if you want to know more, if you download the sample code and take a look, hopefully, you'll see what's going on. As we go back to the slides.

Ok, so that's our demo. So that's it for watching for changes in your application. Just to summarize a little, I use an Instant Message Framework on the IMService class inside it. You can get presence information from iChat into your application. You can get notifications whenever any of this information changes and then you can display information about the user's presence.

You can display the information about the presence of the user's buddies and your application, just like we do in Mail or Address Book card, even the more rich information that's available on the Menu extra and some other information besides. So that's it for the Instant Message Framework. Eric will now talk to you a little more about how you can control iChat from your application as well as just seeing what it's knowing about.

Thank you, Jamie. My name is Eric St. Onge, and today I'm going to talk to you about controlling iChat. And roughly this is going to cover two areas. We're going to talk about iChat's AppleScript API and we're going to talk about the Scripting Bridge, which, that you can then use to take advantage of iChat through the Scripting Bridge.

But to begin with let's talk about the AppleScript API. So, like I said before, the AppleScript API lets you control iChat using AppleScript, and new in Leopard you can also run AppleScript in response to events that happen in iChat. So just to kind of give you a high-level overview.

Is everybody here familiar with AppleScript? Anyone? A few. Ok. All right, so AppleScript is basically an English-like language used to write script files that automate the actions of the computer and the applications that run on it. So basically the AppleScript is a Mac OS technology that's basically used for interapplication communication.

Most of the applications that ship with Mac OS X include dictionaries that sort of provide commands that allow you to automate the applications and sort of hook them together to do interesting things. And kind of the same technology that runs AppleScript is actually used for Automator as well. So kind of all these things hook together. I would encourage you to visit the website to take a closer look, but today we'll go through a few examples of AppleScript at least as they relate to iChat.

So, as I said before, iChat kind of, or AppleScript rather, uses dictionaries to sort of build vocabularies and create commands and classes. So if you want to follow along today, the application that you can open is Script Editor, which is in Applications/AppleScript and it has the icon that you see here. It's the little scroll with the pen.

Once you open that application you'll want to go to File > Open Dictionary. Under that menu you'll actually see a list of all the applications that we've detected or Script Editor has detected that have dictionaries and then you can pick whichever one you want to open. Obviously for this talk we'll want to look at iChat.

So if you're running Leopard you'll see something like this. Basically to sort of give you a high-level look at this window, in the left most pane you're going to see different suites. These are collections of commands and classes that allow you to do things in AppleScript, and in this case there are two that are sort of added to iChat. There's an iChat suite and the Event Handler suite.

The top two are the Standard suite and the Text suite are kind of common across all applications that sort of have dictionaries. So in the middle column, once you've selected a suite, you'll see the commands and classes for that particular suite. And if you were to pick one of those commands or classes you would see a better description on the right sort of telling you the properties of a class, you know, maybe some tips on how to use it and just basically documentation.

So if you were looking on Tiger you would actually see something like this. Tiger has a few different commands available to you to kind of let you do some basic things like send invitations, log in, or log out and kind of look at the services that are currently available.

So, for instance, you could set your status message through it. But today we're going to talk about Leopard, which as you can see, is greatly expanded. And really for the purposes of this talk we just want to kind of look at the two columns so we'll just zoom in a little bit.

So the first thing that I want to mention is that the Tiger commands still work on Leopard. If anyone here has any script that runs on iChat's Tiger AppleScript dictionary, it's still supported for Leopard. But kind of the new things we've added are more interesting. There are new commands for text chats.

So, for instance, there's a entire text chat object exposed to you that you can send messages to, you can get the status of, you can get the participants of, and things like that. You can accept or decline incoming text chat invitations, and additionally you can invite people to text chats as they're happening.

Additionally and similarly added there are new commands for AV chats. There are audio and video chat objects, which you can, you know, invite people to, again. You can accept or decline audio and video chat invitations. And you can also request and stop recording via AppleScript. A new feature in Leopard is actually AV chat recording and, like I said, it's exposed. Additionally file transfer is exposed. So if you want to use iChat as a file transfer mechanism in your own application, perhaps to automate some file transfer in your workflow, you can do that. You can send files or you can accept or decline file transfer invitations.

And, like I mentioned before, there are event handlers and this is actually the fourth suite. I'll talk about this a little more in depth later but basically this is going to provide you with a command that you can implement to sort of react to something that happens in iChat. But to kind of take a closer look, we'll just take a brief look at the AppleScript object model. As you might expect it's kind of similar to the Instant Message Framework, but it's a little bit different so I'll go into some of the differences.

So the first class we want to talk about is the service. Now, if you remember from Jamie's talk about the Instant Message Framework he said that at any time there are at most three services that are exposed to you through the Instant Message Framework. In the AppleScript API this isn't true. You're actually going to get every service exposed to you separately.

So in the case here where we have five buddy lists you're going to see that you can actually get access to each one. So we've got two Jabber lists, two AIM lists, and a Bonjour list. So you're actually going to have these five buddy lists available to you to do things if you need more fine-grained control than you can get through the Instant Message Framework.

So here's kind of a sample script that you could run to sort of get the services that are available in iChat. If you were actually to just type this in to Script Editor and click run, you would get output like this. And basically it's going to give you an array of all the services that you have configured in iChat.

And as you can see, kind of to go through a little bit, the brackets indicate that it's an array. Service is telling you the type of object that has been returned to you. It's going to give you an ID. If you were to run this today the ID you would get would probably be something like a GUID, kind of a longer, you know, text and string kind of thing. But for the purpose of this we'll just pretend they're integers. So, in this case, since we have five buddy lists we're going to get five service objects back.

So that's kind of good. You can get all five, but in most of the case you're not going to want to do something with five services at any time. You're really only going to deal with one. So, as I mentioned before, AppleScript is kind of an English-like language, so the syntax to do it is pretty much like English. So, whereas previously we were just getting the services, now we're going to get the first service whose service type is AIM.

So service type is a property on the service object and we just want to get the first one that is AIM. So, in this case, if we were to run this we would get service ID, with an ID of 300, so that we can find the first AIM service has an ID of 300. And then we can get the name property of that service. In this case it's going to be AIM buddy list. So the name is actually going to be the name that appears at the top of the buddy list window.

So the next class that we need to talk about is the buddy. And a buddy is basically a person in the buddy list. So every service contains multiple buddies. It's pretty straight forward. So buddies exist both on the application level and on the service level. So if you were to run this sample script, this is kind of assuming that we have a service object that we've set, perhaps from running our previous, you know, AIM service script and then you can get the buddies from that.

And if you were to run this you would see something similar to what you get when you ask for the list of services. Again, it's going to be an array. It's going to give you a buddy and it's going to give you an ID. And the ID is basically the account that contains that object, or at least it's identifier, a colon, and then the buddy's handle on that service.

So, the next thing that is exposed to you in Leopard, and this is actually completely new, is chat objects. So, as I mentioned before when I was kind of going through it, text chat and AV chat objects are now both exposed to you in the AppleScript dictionary. So let's kind of go through some sample AppleScripts.

This is basically going to follow the basics that are available to download under the iChat AppleScript sample. I'll just go through kind of some of the syntax that you would use to sort of create these objects and you can follow along if you like. So for a new text chat, this is kind of the script you would run.

In AppleScript first you have to direct your, your commands to a specific object. In this case, we're going to tell the application iChat to do something. So we're going to direct it that way. Next, we're going to create a new variable called theTextChat, kind of the standard in AppleScript is to name variables by what they are, saying, you know, the object. So since we're going to create a text chat, we'll call it theTexChat.

Next, we're going to make a new text chat with properties and this is basically an initializer for theTextChat object in AppleScript. This basically is similar to an Objective-C initializer or C++ or Java constructor. We're going to pass in a dictionary, that you can see here, with a participant's array. So basically the properties is basically, it's a dictionary. So in the left-hand column you'll see there's a key named participants and on the right you're going to specify the participants that are going to take place in that chat.

In this case, we're going to just, you know, start a chat with a single buddy named SmarterChild. You'll notice here that actually we haven't provided an identifier specifically for the buddy. You know how I said before you need to, the ID is actually, that the ID of the service, the colon, and then the handle, iChat's actually smart enough to look up this object for you if you just give it a name. So we're going to look for a buddy named Smarter Child on whichever service we find it on.

And then at this point we'll actually have a text chat object that we can send commands to. So here we'll just send Hello, SmarterChild! to that object. And we would end up with a window like this in iChat. And Smarter Child is actually just a bot that's available to you if you want to, you know, it can tell you the weather and news stories. So it's available pretty much all the time.

So that is the new text chat object. And as I said before, audio and video chats are exposed to you as well, and, actually, the syntax to create them is very similar, whereas this is make a new text chat. Make new audio chat is just make new audio chat and it's basically the same syntax. It's going to take, you know, the same kind of properties, the same kind of participants and it's going to give you something similar, basically an audio chat.

So something we've talked about before, and I've actually heard some confusion about this, is screen sharing. Screen sharing does still exist in iChat and Leopard, as Jamie said, and it's actually exposed to you through AppleScript as well. And since screen sharing is basically always running in audio chat as well, it's actually just an additional property that we add to an ongoing audio chat. So as you can see here, as well as providing the participant with which you want to start screen sharing, we provide the direction of the screen showing. So screen sharing: local screen is going to basically share my screen with my buddy.

And if you run this script you'll get something like this. Ok, and finally, is video chats. Like I said before, if you're making new audio chat and make new text chat, same kind of thing just make new video chat, specify the properties, and you'll get a video chat object. In Tiger we also added multiway video.

This allows you to chat with four video participants or ten audio participants including yourself. And all you need to do is specify multiple participants when you create the chat object. So here we're going to specify two buddies and you're going to end up with a multiway video chat. So here, for instance, you know, a fun chat with Johnny Ives and Mac.

And finally, a chat room. So we've actually spent a lot of time in iChat and Leopard to kind of improve the chat room experience. And chat rooms are actually exposed to you through the AppleScript API as well. So whereas previously you would kind of want to specify the participant for a text chat, now since the chat room kind of exists in kind of a different space, it's basically an address on a specific service, you need to specify both of those properties.

So here we're going to specify the AIM service and we're going to give it the chat room name of ichatwwdc. At this point, much as, you know, when you were creating the regular text chat, you've just got a text chat object you can then send other commands to, something like that.

So, next I'm going to talk about event handlers. And event handlers are basically AppleScript call backs that can be triggered when events occur in iChat. So basically every action has a corresponding AppleScript handler. So in iChat under Preferences there's an Alerts panel that you can choose and within that panel you can configure iChat to play noises when specific thing hap--when specific things happen, you know, to maybe speak an event when it occurs or, you know, bounce the dock when something happens.

Now you can hook up an AppleScript to that, and I'll show you how to do that in a minute. But basically every event is going to sort of provide, or it's going to callback an AppleScript event handler with the relevant objects for that. So, for instance, when I log in it's going to call the login finished event with the account that finished logging in, likewise for logging out.

Buddy Becomes Available is going to tell you the buddy that became available or became unavailable. And for message received, you're going to get something a little different, since it's a little more complicated. So let's take a closer look at the message received handler. So, as I said before, everything, basically, it's going to give you the relevant objects for message received.

So as you can see since the script is not actually be going to telling iChat, it's not going to tell iChat to do something specifically, iChat is going to tell the script to run. We're not going to tell application iChat to do anything. We're going to say using terms from application iChat, and this is basically going to tell this script to compile using iChat's dictionary even though it's not going to directly do anything.

But next there is actually the message received handler. So kind of the way you define a method or an event in AppleScript is saying on. So on event occurred, maybe like you would see in some other languages. And it's going to provide the objects that, that came with that message.

So the text message that was actually sent, the buddy that sent it, and theTextChat object in which it was sent. And once you get through this, I mean, at this point you can really run anything you want. In this case, we would just display a dialog saying, you know, "I got a message", for instance. So let me kind of give you a demo.

So here I'm just going to run off some of the iChat AppleScript samples, basics. And first I'll just start with a new text chat just to kind of go over it a little bit. So if you open this up, I've already compiled this, but if you go to the bottom of the script this script is actually very simple.

We're just going to display dialog, you know, asking the handle of the buddy to chat with. We're going to take the result of that and then we're going to make a new text chat with that buddy. So I'll just start that here. I'll enter Jamie's handle, and now we have a text chat. And I'll say hello.

( Typing )

And Jamie can respond, you know, kind of any way he likes.

( Typing )

Thanks, Jamie. Ok. So that's a, that's a new text chat. Likewise you could do a new video chat and, you know, as I showed you before it's just make new video chat rather than make new text chat. If I click run,

( Typing )

enter Jamie's handle, and here it is.

It's just a chat that was started by AppleScript. Thanks, Jamie. So next, let me show you something a little different. As you can see in the iChat AppleScript samples we've got a few things that are available to you. Some of these are Event Handler, some of them are basically just, you know, straight up script. But let's take a look at one called Chatbot-Eliza. And Chatbot-Eliza or Eliza is actually kind of in, it's basically a text-based psychoanalyst.

So what it's going to do is it's going to take text input, rephrase it in the form of a question, and kind of ask it back to you. And we can actually hook this up to iChat via Event Handlers. So if we go down to the bottom, you see we have runChatbotEliza method that we've defined, which we'll get to in a second.

But a little further down below that we have a few Event Handlers. So, for instance, received text invitation is here. This is basically going to be the Event Handler that is called whenever a new text chat is hooked up, the buddy that sent it, and the chat that it was sent in. Since it's an invitation it's going to show up as a little notifier in the upper right corner of your screen. You can just accept that and make, kind of accept it as a full-fledged chat.

Then we'll just send a message back saying, you know, "Hello! What can I do for you?" Or, "What can I help you with today?" Similarly for a message received all we're going to do is we're going to take the message that was sent, we're going to pass it into Eliza and then we're going to send the response back. So let's take a closer look at Chatbot-Eliza. This is actually pretty straight forward. AppleScript isn't really doing anything very much here. We're actually just going to run a command-line tool that's going to, sort of, hook it up for you.

So there is a, there is a Chatbot-Eliza perl script that will need to be copied in, which I'll show you in a second. But all this is going to do is it's going to run this shell script using the do shell script command. It's going to take the response and it's going to return that response, which we will then send back.

So let's kind of actually hook this into iChat. So if I got into iChat's Preferences, if I go to Alerts, as you can see here there are all the different events you can configure. I had been talking about Message Received previously. So let's look at that. I will go to run AppleScript. I've already got the script ready so I'll just say Open the script folder. At this point I'll copy in the AppleScript file and sort of the perl script I need. And then within iChat I'll choose run Chatbot-Eliza. I'll also do the same for a text chat invitation.

So now, at this point, my machine is configured to kind of run Chatbot automatically. So I'll just, I'll just step away from the machine. And if Jamie were to go and were to go and send a message, you can see that it's, that Chatbot-Eliza is just going to pick it up for you. And now you can just chat away.

We actually had an experience with our, one of our program managers or one of our project managers who I accidentally left this running on, it took a good seven or eight tries to catch on. So, so at this point, Jamie can actually go and do the same thing on his side, you know, for an extra bit of fun.

( Typing )

So now he's got it hooked up and if I say hello, you can see that now you have, you know, two Chatbot-Eliza's talking to each other, not really having anything very interesting to say...

( Audience talking, clapping )

But what you can see is happening is actually you notice as the conversation is going on the, kind of, the chat's slowing down.

And iChat's not actually slowing it down for you, this is actually AIM kicking in. If anyone has ever tried to send too many messages on the AIM service, kind of one after the other, it's actually going to rate limit you. So you can't actually just go and write a script that's going to spam everyone in your buddy list.

AIM is actually going to actively prevent you from doing that. iChat has a few guards in place to do that as well. So we're going try to protect you, and also kind of help you from taking, kind of disallow you from taking advantage of this for nefarious purposes. So...

( Applause )

Thank you. So, that's Chatbot-Eliza. You can go back to the slides.

So, that was Chatbot-Eliza, like I said, that's available to you dev for download. If you want to install it you can do that. You will also need to download the Chatbot-Eliza perl module. We have it just to kind of look on your desktop, but if you actually want to do it properly through perl you could do that.

So next, let's talk about something a little different, let's talk about the Scripting Bridge. And the Scripting Bridge will allow you to control iChat with Objective-C. This is not through the Instant Message Framework. This is actually by way of the AppleScript API. So the Scripting Bridge is actually going to go and it's going to build a dynamic API based on the AppleScript API in really whichever language supports the Scripting Bridge. At this point it's really Objective-C, Ruby, and Python.

Third-party developers will probably develop other ones, but for now, or today anyway, we're just going to talk about Objective-C. It's basically going to make every AppleScript command available to whichever language is supporting that bridge. Event Handlers, unfortunately, cannot do this directly. What you could do is you could write an Event Handler that sends an AppleScript command to your own application, which you could then, sort of, do whatever you like with. But you cannot write an Event Handler in Ruby or Objective-C or Python. It always has to be AppleScript.

It's also worth pointing out that this works with any scriptable application. iChat has not done anything to adopt the Scripting Bridge. Just by us having a scripting dictionary the Scripting Bridge is going to sort of build this for us. This is actually true for any Mac OS X application that has an AppleScript dictionary, including your own. So if you needed one more reason to make your application scriptable, this is a pretty good one.

So let's talk about using the Scripting Bridge with iChat. Again, we're going to talk about Objective-C. The first thing you're going to want to do is build the Objective-C headers using the sdp command. For iChat we're going to use the sdef command to sort of dump AppleScript's, iChat's AppleScript dictionary out and then we're going to pass it into the sdp command.

This is basically going to create a header file called iChat.h which you can then include in your own Objective-C project. And as you can see, here's kind of what you'll see. It's basically going to create an Objective-C counterpart for every AppleScript command and class that we see or that it finds.

So at this point you can dynamically create and use these objects through Objective-C. So, for instance, in this little script here all it would do is at first it's going to look up the class, look up the application class, it's going to initialize it, then it's going to set its statusMessage. So, kind of the counterpart AppleScript of this would be, you know, tell application iChat setStatusMessage to using the Scripting Bridge. The Objective-C syntax is actually very close.

It's also worth pointing out that if you ever use NSAppleScript in your application the Scripting Bridge is a much easier and a much faster way to do it, rather than sort of dynamically building and, you know, generating your own AppleScript's programmatically. You know, just in, build the header file, include it in your project and use it that way. So, I'll just kind of walk through some code. We have a demo available. iChatStatusFromApplication, which I have open here.

And the project is pretty simple. So I've already gone ahead and I've wrote, I've included the header file. But all this application is going to do is basically just set iChat status to the current frontmost application. So one thing we will actually have to do here is enable assistive devices. So I'll turn that on. And I'll just kind of run the application to show you what it's doing.

So here's this kind of the window, it doesn't do all that much. I'll just leave it right below iChat status. But, sort of, as I browse around to different applications and launch different things, if I launch Calculator, for instance, it's just going to set my status image and status message to that in iChat.

So if I wanted to start, you know, chats or whatever. And there it is. So if you really want to tell everyone what you're doing all the time, here's kind of a sample that you could use as a basis for that So let's look at the code for that. There's really only one class that you need to look at, just the ISFAController.

And primarily, this is a, it's a pretty simple application. The first thing is when the controller awakes from the NIB we're going to create a reference to the iChat application, much like you saw on the slide where I, kind of, showed some demo syntax. We're just going to do classForApplicationWith BundleIdentifier and then initialize it. And we'll just keep a local reference to that.

So, sort of, as we continue, you'll see we're just going to register for a few workspace notifications. So when an application launches or terminates we'll kind of keep track of that so we can update iChat status appropriately. And basically at this point we're just listening for notifications once the application has launched.

So applicationLaunched, this is one of the call backs for those workspace switch notifications, going to call an applicationSwitched method. If we take a closer look at that, this is pretty simple. What it's going to do is we're going to ask the workspace for the active application. So it's going to give us the front most application at this time.

We're going to get the application's process identifier. This is just so we can keep track of which process identifier is, you know, to which application and so we can just kind of pick out when it changes. So, if the process identifier has switched and it's not our own application's process identifier, we'll continue on.

If iChat is running, it's pretty straight forward. If a status is set to available, all we're going to do then is we're going to get the icon for the front most application. We're going to get a tiffRepresentation, since that's what iChat is expecting. Then we're going to set that on the iChat app. This is actually a Scripting Bridge call right here. It's, it's kind of misleading that it's actually just, you know, setImage, it's really an Objective-C Scripting Bridge call to iChat.

Likewise we have an icon view in our own application just to kind of show the status there as well. We're going to set the image there. Similarly for the statusString we're going to generate, you know, saying using the front most application. We'll set iChat's statusMessage, again, this is a Scripting Bridge call. And we'll also set the label within our own application to that string. And as you can see it's pretty simple.

So one thing I didn't mention yet is the Join Chat Room button. So if I push that, at this point I'm in the iChatstatus chat room. So this is actually kind of, kind of a neat way, if you really want to talk about the iChat status demo and really how tremendous it is, there's an AIM chat room available to you. And let's look at that code too. So this is the action that is called when the chat room button is pushed.

First we're going to look at the services available in iChat and we're actually going to want to look for an AIM service since the chat room really only exists on AIM. And we're going to iterate through the services to find the first AIM service whose status is set to connected.

And if we do find one we're going to then create a dictionary. Just as we did in AppleScript when we created a new chat room object there, we specify the service and the name of the chat room, which is basically the chat room's address. Then we're going to initialize a text chat. So we'll have to look up the class for the scripting class called textChat.

We'll initialize it with the properties we create above. And then something a little different from the AppleScript API or from AppleScript directly, you actually have to go and add this to the textChat objects within iChat. But once you do that you end up in iChat, oh, thanks, people.

( Laughs )

You end up, you, thank you. You end up in the iChat status chat room. Ok. So that is a Scripting Bridge. And again, that sample is available to you. We can go back to the slides.

So that's just kind of a few examples of what you can use the Scripting Bridge for, but, as I said before, all the functionality that exists in iChat's AppleScript dictionary is also available through the Scripting Bridge. So you could, for instance, transfer a file. If you pass an NSURL to the send command it's actually going to send the file at that URL, a pretty simple way to do it.

You could do live help for your users. In addition to, you know, starting a chat with a chat room you could just have someone that you, you know, one of your employees providing, you know, kind of help desk services on AIM. You could start a text chat this way.

And, kind of the example that I showed you in the iChat status, is, you know, going to a chat room with a specific name. So if you want people to talk about your chat room or talk about your application in a chat room to meet up, you could provide that as well.

So, that's kind of it. Let's kind of take a closer look and kind of step back and see what we've talked about today. So we talked about three technologies. We talked about the Instant Message Framework, iChat's AppleScript API, and the Scripting Bridge. And to get information from iChat you can actually use any of these technologies for kind of ad hoc searching and like looking up the status of someone. AppleScript and the Scripting Bridge are perfectly good ways to do that.

But for, kind of, full-fledged notifications and sort of real-time status as it happens in iChat, the Instant Message Framework is really the way to go there, so two checks there. To control iChat the Instant Message Framework actually doesn't provide anything. So there is no control provided by way of the Instant Message Framework. If you want to do that you'll have to use AppleScript and since Scripting Bridge is basically just the AppleScript API you can do it through the Scripting Bridge as well.

Now for Event Handling, as I said before, that's AppleScript only. It does not bridge through the Scripting Bridge. But you could create an AppleScript that you could hook into iChat's Event Handlers that then does something through your own scriptable application. And, though we didn't talk about it today, iChat Theater is also available through the Instant Message Framework. I would encourage you to come to your session tomorrow at 2:00PM in the Presidio to hear more about iChat Theater.

So kind of in the summary, as a summary, what we really want to say is that iChat is not just for users. You can take advantage of it in your own application to sort of connect your users together and provide kind of a better and, you know, new communication experience.

You can also display presence information in your application to provide a more consistent experience as you might see in mail or Address Book and, you know, other applications on Mac OS X. But it also allows you to kind of take advantage of iChat for automation in your own application by way of the AppleScript API or AppleScript and also through the Scripting Bridge. So if you don't want to use AppleScript you could do it by way of Objective-C, Ruby, or Python and probably other languages eventually.

So for more information, please contact Matt Drance. He's the evangelist for our technologies. We've also set up a mailing list with which you can, you know, you can ask us questions about iChat Theater or the Scripting Bridge or the AppleScript API. And the samples that we talked about today and a few more are available on the attendee site if you want to take a look.

We've also got a few labs that might be interesting. If you want to talk about application scripting and scriptability, there's a Lab tomorrow at 3:30PM. Likewise at the same time there's actually an iChat Lab. So if you have questions about iChat scripting or the Instant Message Framework or iChat Theater, you can talk to us then about it too.