== The Cocoa XML-RPC Framework The Cocoa XML-RPC Framework is a lightweight, simple, and easy-to-use XML-RPC client written in Objective-C for use in OS X applications. An XML-RPC request can be sent asynchronously or synchronously, depending on the intentions of its use. == Requirements The Cocoa XML-RPC Framework has been built, and designed, for OS X 10.4 or later. The framework relies on NSURLConnection and NSURLRequest for HTTP transport, and NSXMLDocument for parsing XML-RPC responses. == Usage The following examples of the Cocoa XML-RPC Framework assume that the included XML-RPC test server are running. The test server can be found under: XMLRPC\Tools\xmlrpc-server The XML-RPC test server is written in Java and utilizes the Apache XML-RPC server library. To start the server simply call Ant from the same directory where the build.xml file is located: ant The target is optional, omitting this argument will execute the default target (the default target is "run"). The following targets are available: - compile - jar - run - clean More information on the XML-RPC test server can be found below. = Asynchronous Making an asynchronous XML-RPC request is probably the best way to communicate with an XML-RPC server. After creating an XMLRPCConnection the XML-RPC request is sent to the XML-RPC server in the background. This allows the requesting application to continue performing other functions. Sending an asynchronous XML-RPC request is simple: - (void)sendRequest { NSURL *URL = [NSURL URLWithString: @"http://127.0.0.1/"]; XMLRPCRequest *request = [[XMLRPCRequest alloc] initWithHost: URL]; [request setMethod: @"Echo.echo" withParameter: @"Hello World!"]; [request setUserAgent: @"XML-RPC Example"]; XMLRPCConnection *connection = [[XMLRPCConnection alloc] initWithXMLRPCRequest: request delegate: self]; if (connection == nil) { NSLog(@"Connection failed."); } } It is important to understand that the caller is responsible for releasing the connection and response objects at the end of the connection response and connection failure delegate methods. Do not attempt to release the connection object anywhere but within these two delegate methods. - (void)connection: (XMLRPCConnection *)connection didReceiveResponse: (XMLRPCResponse *)response forMethod: (NSString *)method { if (response != nil) { if ([response isFault]) { NSLog(@"Fault code: %@", [response faultCode]); } else { NSLog(@"Response object: %@", [response responseObject]); } NSLog(@"Response source: %@", [response responseSourceXML]); } else { NSLog(@"Unable to parse response."); } [response release]; [connection release]; } = Synchronous Synchronous XML-RPC requests may be suitable in some situations. Unlike sending an asynchronous request, a synchronous request is made in the foreground causing the calling application to await an XML-RPC response. - (void)sendRequest { NSURL *URL = [NSURL URLWithString: @"http://127.0.0.1/"]; XMLRPCRequest *request = [[[XMLRPCRequest alloc] initWithHost: URL]]; [request setMethod: @"Echo.echo" setParameter: @"Hello World!"]; [request setUserAgent: @"XML-RPC Example"]; XMLRPCResponse *response = [XMLRPCConnection sendSynchronousXMLRPCRequest: request]; if (response != nil) { if ([response isFault]) { NSLog(@"Fault: %@", [response fault]); } else { NSLog(@"Response object: %@", [response responseObject]); } NSLog(@"Response source: %@", [response responseSourceXML]); } else { NSLog(@"Unable to parse response."); } [request release]; [response release]; } A response will always return nil upon creation if it is unable to parse the XML data. However, in the case of a synchronous request, a nil response can either mean the response could not be parsed, or the connection failed to send the request. An asynchronous connection will return nil if it fails to send the request. The response passed to the connection:didReceiveResponse:forMethod: delegate method will be nil if the response object is unable to parse the XML response data. Also note that you may have access to the raw XML source to either the request and/or response. Though you may be able to extract the source from the request at any moment in the object's life, it is always best to get the source after invoking the setMethod:withParameters: or setMethod:withParameter: methods. If you ask for the source too early, you won't receive the fully created XML request source. == Using the XML-RPC test server The XML-RPC test server is a simple Java application that allows developers to easily develop software with Cocoa XML-RPC Framework. The test server is built on top of the Apache XML-RPC library. Using the test server is easy, simply call Ant from the same location as the build.xml file: ant The default target is the "run" target, which will compile the Java source code, build the executable JAR file, and run the application. Included with the test server is a server.sh script, this Bash script will launch the test server (if it has already been built with Ant). = Creating XML-RPC server handlers The XML-RPC test server exposes the methods defined in server handlers. Each server handler is simply a Java class that is registered with the Apache XML-RPC library. Here is an example of the Echo handler provided in the distribution: public class Echo { public String echo(String message) { return message; } } This handler simply takes a message provided in the XML-RPC request and returns it in the XML-RPC response. To register this handler with the XML-RPC server simply add it to the propertyHandlerMapping in Server.java: import com.divisiblebyzero.xmlrpc.model.handlers.*; ... try { propertyHandlerMapping.addHandler("Echo", Echo.class); this.embeddedXmlRpcServer.setHandlerMapping(propertyHandlerMapping); } catch (Exception e) { this.controlPanel.addLogMessage(e.getMessage()); } The handler is now available to any incoming XML-RPC requests. == What if I find a bug? The Cocoa XML-RPC Framework has been developed on my free time. Any comments, questions, bug reports and/or suggestions can be sent to eczarny@gmail.com. If you find this framework useful I would appreciate receiving the necessary credit where ever due. == Acknowledgments The Base64 encoder/decoder found in NSStringAdditions and NSDataAdditions have been adapted from code released by Dave Winer and Brent Simmons. Dave Winer wrote the original Base64 encoding and decoding routines. Brent Simmons adapted Dave Winer's code for use with Objective-C. == License Copyright (c) 2008 Eric Czarny. The Cocoa XML-RPC Framework should be accompanied by a LICENSE file, this file contains the license relevant to this distribution. If no LICENSE exists, please contact Eric Czarny .