Using iChat Services and Buddies

This article describes how to access information about iChat services and buddies from a Cocoa application.

The Preferences panel in iChat is used to setup a user’s different accounts. The account type specifies the type of service for the account. For example, the account type for a .Mac account is set to .Mac in the Preferences panel where the underlying service is AIM. Jabber and Bonjour are other iChat services.

Services store information about an account on the server—information about the status of the user and the user’s buddies. This same information is accessible from a Cocoa application using the IMService class. For example, you can get the screen names and login status of all your buddies.

The rest of this article explains how to get this iChat information.

Getting User Status

Typically, you use the Instant Message framework to simply check the iChat status of the current user.

You can check whether the user is available and display an appropriate icon in your application. For example, this code fragment uses the imageNameForStatus: class method as follows to get a status image to display:

NSImage *anImage = [NSImage imageNamed:[IMService imageNameForStatus:[IMService myStatus]]];

You can also get the status and idle time of the current user. This code fragment uses the results of the myStatus class method to create a human-readable message:

    NSString *message;
    switch ([IMService myStatus]){
        case IMPersonStatusUnknown:
            message = @"Unknown";
        case IMPersonStatusOffline:
            message =  @"Offline";
        case IMPersonStatusIdle:
            message =  @"Idle";
        case IMPersonStatusAway:
            message =  @"Away";
        case IMPersonStatusAvailable:
            message =  @"Available";

Use the myIdleTime class method to get the idle time.

Getting Status of Services

Any given user may have multiple accounts on multiple services—for example, have both a .Mac and Jabber account. You can use the allServices class method to get an array of the services or the serviceWithName: class method to get a specific service. For example, this code fragment iterates through each instant message service:

        NSEnumerator *serviceEnumerator = [[IMService allServices] objectEnumerator];
        IMService *imservice;
        while (imservice = [serviceEnumerator nextObject]){

Once you have an IMService object, you can access information about the service using a number of methods. You can use either the localizedName or localizedShortName method to display a human-readable name of the service. For example, the name of the .Mac service might be AIM whereas the localized name might be AOL Instant Messenger. In contrast, the string returned by the name method is not localized and should only be used in a later call to the serviceWithName: method.

You can also check the status of the service itself to determine if the user is logged in or not. Note that the myStatus method always returns IMPersonStatusOffline unless the user is logged into a service. This code fragment creates a human-readable message describing the service status:

    NSString *message;
    switch ([service status]){
        case IMServiceStatusLoggedOut:
            message = @"Logged Out";
        case IMServiceStatusDisconnected:
            message =  @"Disconnected";
        case IMServiceStatusLoggingOut:
            message =  @"Logging Out";
        case IMServiceStatusLoggingIn:
            message =  @"Logging In";
        case IMServiceStatusLoggedIn:
            message =  @"Logged In";

Accessing Buddies

You can get a list of all the user’s buddies and individual information about each one. You obtain the buddy list using the infoForAllScreenNames method. This method returns an array of dictionaries where each dictionary contains key-value pairs that describe a buddy. For example, this code fragment prints the screen name for each buddy using the IMPersonScreenNameKey key.

NSEnumerator *accountEnumerator = [[service infoForAllScreenNames] objectEnumerator];
NSDictionary *accountInfo;
while (accountInfo = [accountEnumerator nextObject]){
    // Print the account screenname
    NSLog(@"Buddy with screenname=%@",
      [accountInfo objectForKey:IMPersonScreenNameKey]);

Other properties of a buddy are first name, last name, email address, idle time, busy message, and picture data if available. See IMService Class Reference for a complete description of these properties.

You can also display an image for the status using the imageNameForStatus: class method as shown in “Getting User Status.”