While there are a few stand-alone services, it's more common for an application to export some of its functionality via this mechanism. Applications that export services can be combined with others easily.
To advertise a service, you need to call the NSRegisterServicesProvider() function. This associates a class with a service, like this:
NSRegisterServicesProvider([MyService new], @"SomeServiceName");
If you are writing a stand-alone service, you need to do this in your main() function, otherwise you can do it in you application delegate. Prior to OS X 10.5, you also needed to configure the run loop to act as a server for system services, like this:
[[NSRunLoop currentRunLoop] configureAsServer];
You can skip this step on 10.5 and newer. The class that provides the service needs to implement a method like this:
- (void)serviceName: (NSPasteboard*)pboard userData: (NSString*)userData error: (NSString**)error;
The first argument is the pasteboard that contains the input and is also used to return the service's output. The userData parameter is usually not used and the error parameter is used to return errors.
The first part of this selector, serviceName, is the name of the service. A single object can implement several services with different names. Before this will work, you must include some keys in the application's Info.plist. The NSMessage key gives the first part of the selector name used to invoke the service.
There are a few other keys in this that are important. NSSendTypes and NSReturnTypes describe the pasteboard types that the service accepts and returns, respectively. You don't need to specify both for a service: you can either consume data and not return anything, or return data and not consume anything. Most importantly, the NSMenuItem key provides the name of the menu item.
There are a few other keys, which you can find in Apple's developer documentation for services, including a string to be passed in to the userData parameter in the services menu.
Implementing a service method in an application is usually only a few lines of code calling other, existing, methods to do the conversion. Adding all of the required entries in the property list is a bit more tricky. For a complete example, take a look at TextEdit's Info.plist. The NSServices key contains an array describing two services, one for creating new files from selected (rich) text and another for opening files from a selected filename.