14 Jun 2009

XML-RPC on the iPhone

Posted by kilbot | Filed under: News, Programming

This week I’ve been porting a simple J2ME mobile phone application to the iPhone. The J2ME application allows users to login and exchange data with a web application via XML-RPC, so naturally I was keen to use the same server-side scripts for the iPhone app. As far as I know, there is no no specific open source framework available for XML-RPC on the iPhone, but the folks at WordPress for iPhone have rolled their own which is available under the GNU General Public License, and with a little fishing around I was able to get it up and running in my own app. Basic instructions after the jump…

The first step is to download the WordPress for iPhone source code, either via SVN or directly through Trac (Link to the latest trunk: http://ios.trac.wordpress.org/browser/trunk).

When you extract that zip you will see a folder named Classes and inside that a folder named XMLRPC, drag the XMLRPC folder into your project. You will also need to grab NSString+XMLExtensions.h and NSString+XMLExtensions.m and drag them into your project.

That’s all the required files for the XML-RPC framework and now implementing is fairly straight forward. You need to put the following to your header file:

#import "XMLRPCResponse.h"
#import "XMLRPCRequest.h"
#import "XMLRPCConnection.h"

and to your .m file you need to add something like:

- (NSString *)loginToServer {
	NSArray *args = [NSArray arrayWithObjects:@"test",nil];   // the param(s)
	NSString *server = @"http://example.com/xmlrpc";         // the server
	NSString *method = @"loginUser";                        // the method
	XMLRPCRequest *request = [[XMLRPCRequest alloc] initWithHost:[NSURL URLWithString:server]];
	[request setMethod:method withObjects:args];
	id response = [self executeXMLRPCRequest:request];
	[request release];

	if( [response isKindOfClass:[NSError class]] ) {
		return nil;
	}
	else {
		return [response valueForKey:@"key"];          // the response key
	}
	return nil;
}

- (id)executeXMLRPCRequest:(XMLRPCRequest *)req {
	XMLRPCResponse *userInfoResponse = [XMLRPCConnection sendSynchronousXMLRPCRequest:req];
	return [userInfoResponse object];
}

You need to enter the appropriate values where I’ve commented, but this bare bones example should get you started. You can see more examples by sifting through BlogDataManager.m file in the WordPress for iPhone project.

  • Leoganda

    Hi, it’s really good article!
    I’m newbie in Iphone development, do you have complete article how to use this xml rpc and linked to the UI??

    Thanks

  • Leoganda

    Hi, it’s really good article!
    I’m newbie in Iphone development, do you have complete article how to use this xml rpc and linked to the UI??

    Thanks

  • Hi Leoganda, I don’t have a complete article but I probably help you put together some basic code.. what is the task you are trying to complete?

  • Hi Leoganda, I don’t have a complete article but I probably help you put together some basic code.. what is the task you are trying to complete?

  • Cool, do these classes convert the array returned to an NSArray?

  • Cool, do these classes convert the array returned to an NSArray?

  • The returned object (*response in the case above) is a NSDictionary, that way you can access the data with key/value pairs.

  • The returned object (*response in the case above) is a NSDictionary, that way you can access the data with key/value pairs.

  • Hi thanks kilbot, I have succeed make simple app with XMLRPC WordPress now :)

  • Hi thanks kilbot, I have succeed make simple app with XMLRPC WordPress now :)

  • Lex

    Hey Kilbot,

    thanks for the info. I need to use XMLRPC for my iPhone app, I tried implementing an example pretty much like what Leo has on his site (http://www.leoganda.net/xml-rpc-on-iphone/). Even if I define response as an id and not NSString, I get a “NSInvalidArgumentException, reason: *** [NSError object]: unrecognized selector sent to instance …” error when I return the response as an object. Have you encountered this as well?

  • Hi Lex, the response is returned as a NSDictionary, so depending on how you are trying to access data within that object you could be getting the NSInvalidArgumentException error.

    Try logging some notices in the app to see where it is failing, eg:
    if( [response isKindOfClass:[NSError class]] ) {
    NSLog(@”Something went wrong … there was no readable response”);
    return nil;
    }
    else {
    NSLog(@”key: %@”,[response valueForKey:@”key”]);
    return [response valueForKey:@”key”]; // the response key
    }
    return nil;

    Where 'key' is some data you expect to get back from the server.

  • Lex

    Alrite, I can't figure how the returned data strucutre is composed. I tried looking for an NSDictionary strucutre in the debugger, but no success. My response in XML looks like this:

    <methodResponse>
    <params>
    <param>
    <value>
    <boolean>0</boolean>
    </value>
    </param>
    </params>
    </methodResponse>

    I tried using “boolean” and “value” as the key, but that didn't help, I get a “Terminating app due to uncaught expcetion NSUNknownKeyException, reason: NSCFBoolean 0x… valueForUndefineKey: this class is not key value coding-compliant for the key boolean/value/…”

    Does the key relate to the XML at all?

  • Jb

    Lex – check your comment on the WP iPhone app… The keys are dependent on what the XMLRPC service returns… I.E. you're making a method call for some data and what comes back depends on what you asked for and how that XMLRPC service creates the XML…

  • ad

    Hi, I'm trying to develop an application based on your post, and on Leoganda's one, but I'm doing something wrong. My app has an exception everytime.

    Terminating app due to uncaught exception 'NSInvalidArgument
    Exception', reason: '*** +[NSString decodeXMLCharactersIn:]: unrecognized selector sent to class 0x30692800'

    I debugged and found that it crashes on the first line of this function:

    – (id)decode
    {
    [_parser parse];

    NSError *parseError = [_parser parserError];
    if (parseError) {
    return parseError;
    }

    return decodedValue;
    }

    Even though, I still don't know what I'm doing wrong. Some advice would be very helpful.

    Thanks!

  • Lex

    It sounds to me like the argument that is passed to NSString's decodeXMLCharactersIn method is of the wrong type. Make sure that types of your variables support the methods you call on them. This can be tricky due to Objective-C being very dynamic. If you debug and step into the parse method and reach the point where [NSString decodeXMLCharactersIn] is called, you should be able to track down the error.

  • In your technology responsibilities and performance measures. It will pay big dividends and there is the biggest prize for that get to end faster.

  • ad

    Thanks, Lex.

    Now I kinda succeded in establishing a communication between my app and my php WS, but I have some problems with types.

    I created the WS using phpxmlrpc library, do you know if it's compatible with the wordpress library? I sometimes find that I dont get returned a NSDictionary but a String.

    I also would like to know how to send integers or other types to the WS, not only strings.

    Thanks!

  • Guest

    Hi thanks for this example. I'm using SDK 3.1.2 and things compiles fine but when I use it I have a strange problem. I get errors when the rpc function returns a simple string, also if I return a Map the maps has all empty entries?

    Could this be due to the code being old ? Also what are most people using to communicate with server side from the iPhone ? XML-RPC seems to be not as heavily used.

    thanks

  • I haven't developed anything for the iphone since I wrote this article, but the feeling I got at the time was that XML-RPC was the exception rather than the rule for web services.

    I believe that most developers are using simple HTTP calls like POST, GET, PUT or DELETE and then parsing the output, depending on your app this might be XML or JSON or something similar.

    As I say, I haven't played with this stuff for a while, but a quick search on Google turned up some stuff that might be worth looking at:
    http://allseeing-i.com/ASIHTTPRequest/ (a HTTP wrapper in objective-c)
    http://www.mobileorchard.com/tutorial-json-over… (a tutorial for parsing JSON)

    And you should always look at the info and tutorials at developer.apple.com to see if any native functionality will fit your needs: http://developer.apple.com/iphone/library/navig

  • Tim

    Thanks so much for this info. I have been trying to do exactly this for the past week. I am having trouble with some odd parts of it, but I was able to work around it.

  • Abhinav

    I am getting error:
    Domain=NSURLErrorDomain Code=-1202 “The certificate for this server is invalid. You might be connecting to a server that is pretending to be “*******.*****.org” which could put your confidential information at risk.

    Now how to get pass this certificate issue? I know some NSURLConnection public API to use , but with wordpress source code how to use it?????? Please help me

  • Hi Abhinav. It sounds like there is a problem with the security certificate for that subdomain, ie: it’s probably only set up for the main domain. Do you have to connect via https? Perhaps try straight http?

    Other than that I think you will have to fix the security certificate server side because XML-RPC is going to fail with an invalid certificate.

  • Mohd Imran

    This website made me proud.

  • You might be interested in the WordPress for iOS app. It’s completely open source and uses an XML-RPC library.

  • Percy Holl

    I was unfamiliar about this new application XML-RPC on the iphone but from your blog post i got some ideas about usage of this on iphone. Thanks for this useful product information.

    NetSuite

  • Parul

    nice tutorial…please post complete code.