oreilly.comSafari Books Online.Conferences.


AddThis Social Bookmark Button Programming With Cocoa

Incorporating Rendezvous into Your Cocoa Applications, Part 2


Editor's note -- In the first part of this multi-part series, Mike Beam discussed some of the thinking behind Rendezvous (ZeroConf) and how to incorporate this functionality into your Cocoa applications. Now, in part two, he shows you how to build a simple Rendezvous client similar to iChat.

Our Application

Today we'll build the Rendezvous service publisher and browser, and in the next column I'll show you how to give the application the ability to talk to other instances of the application on a network.

In a fit of creative inspiration, I decided to call this application RCE, which stands for Rendezvous Chat Example. Stirring, isn't it?

So that we don't spend half of the column talking about how to build the UI for RCE, I've included in a project folder a completed interface that has been wired up to a controller object. The project folder can be downloaded here.

Let's take a look at the interface so we all know what we're going to be working with. This is the interface that I came up with:

Screen shot.     Screen shot.

On the left we see RCE turned off; on the right it has been started, and as you can see I am the only person running the RCE service on my network. Heed the warning, especially since it contains a typo and is colored red! Blech!

On the left you see the state of the interface when it first launches. The field at the top is where we specify the name of the service that we'll be publishing. This field is connected to the class Controller through the outlet nameField. Since this is a chat application, the service name defaults to the long name of the currently logged in user.

Below nameField is the button that starts and stops the service. You can see in the screenshot on the right how the button title changes from "Start Chat Service" to "Stop Chat Service" and back again when it is clicked. This button is wired to Controller's toggleServiceActivation: action.

The final element of the interface is the table "Mi Amigos" (assuming you're friends with all of the folks on your network). This is a single-column table that displays the list of discovered services on the network. The names that appear in the table are the same names specified in nameField.

In the right you see only my name, since I was the only one running RCE when I took the screenshot (my sales department is working on that). The outlet for the table is discoveredServicesList in the class Controller. Controller has been set up as a data source for discoveredServicesList, so we won't have to implement the NSTableViewDataSource methods ourselves.

Implementing the Application

Let's start implementing this application. The first thing we want to do is perform any initialization in awakeFromNib. Right now there's really only one thing we need to do, and that is fill nameField with some initial value, which as I said would be the full name of the currently logged in user. This name is obtained using the Foundation function NSFullUserName, which we use in awakeFromNib, like so:

- (void)awakeFromNib
    [nameField setStringValue:NSFullUserName()];

The target of the "Start Chat Service" button is the action in Controller toggleServiceActivation:. In this method we call a number of methods that configure different parts of the application when the service is activated, and some methods that do some cleanup when the service is deactivated. When starting a service it is necessary to configure a socket, and an instance of NSNetService that will advertise our service.

Since our application is both a service publisher and consumer of services -- that is, it browses for them and ultimately uses them -- we have to set up the service browser, as well. This is the standard behavior of chat applications that both announce your presence to other chat clients when you sign on (the service publication side of business), and also display others who are signed on (the service browsing side of business).

Here is the implementation for toggleServiceActivation:

- (IBAction)toggleServiceActivation:(id)sender
    switch ( [sender state] ) {
	       case NSOnState:
	           [self setupSocket];
	           [self setupService];
	           [self setupBrowser];
	           [nameField setEnabled:NO];
        case NSOffState:
	           [serviceBrowser stop];
            [domainBrowser stop];
	           [service stop];
	           [nameField setEnabled:YES];

This action is invoked whenever the Start/Stop Service Button is pressed. When this action is invoked, we do a switch statement based on the state of the switch. If the state is NSOnState, indicating that the service should be started, we do what we need to do to set up the various components of the chat service, which includes building a socket, creating and publishing the associated service, and setting up the browser. Finally, we disable the name field to prevent the user from changing the name in the field while the service is running. If the state is NSOffState, then we take the necessary steps to remove the service from the network and stop browsing for other services. This is done by sending stop messages to our NSNetService and NSNetServiceBrowser objects. After stopping these things, we have to re-enable the service name text field so that the user can change the name of their service, if they so choose.

Pages: 1, 2, 3, 4

Next Pagearrow