Blog
Oct 06

Hey WordPress, my apps are hungry for XML-RPC!

We’ve been quite busy here at Grenade lately. We recently launched a WordPress plugin called WooCommerce Events which allows you to add seamless event and ticketing functionality to your installed WooCommerce plugin for WordPress. Keep an eye on our blog for more information about it coming some time soon!

We built a free iOS and Android app which allows you to easily manage your events and ticket check-ins while away from your computer – at your event for example. Since WooCommerce Events is a WordPress plugin, we had to figure out a way in which we could get the apps to communicate with a WordPress site in order to send and receive data to and from it. WordPress makes use of XML-RPC in order to send and receive data.

XML What?!

XML-RPC stands for Extensible Markup Language Remote Procedure Call (try saying that five times fast). According to the Wikipedia entry for XML, XML is a “markup language that defines a set of rules for encoding documents in a format which is both human-readable and machine-readable”. If you’re already familiar with what XML-RPC is, you can skip this section and get right on to the meat! Here is a very basic example of a custom XML document describing some events:

<?xml version="1.0" encoding="utf-8"?>
<events>
	<event>
		<name>Rock concert in the park</name>
		<date>3 October 2015 20:00</date>
		<location>West End Park</location>
	</event>
	<event>
		<name>Hello Kitty Expo</name>
		<date>10 October 2015 10:00</date>
		<location>Main Street Convention Centre</location>
	</event>
</events>

This XML is human-readable and follows a specific structure that a machine will be able to read as well. If you tell the machine you want the name of the second event, it will traverse through all ‘event’ tags until it reaches the second event. Then it will traverse through all the child tags of that event until it finds a ‘name’ tag. It will then return the text value contained within that tag. This will only be possible if the document follows the same established rules for the structure of the data that the machine has also been set up to follow.

XML-RPC is XML that follows a standardised set of rules for how data should be represented or structured. This allows various machines to communicate with each other even if they are completely different platforms and codebases eg. a WordPress site coded in PHP with a MySQL database will be able to communicate with an iOS app coded in Objective-C or Swift or an Android app coded in Java.

XML-RPC Types

An exchange of data occurs when a client machine issues an XML-RPC request to a server machine for example. The server that receives the request will do some processing based on the data received in the request from the client such as fetching specific data from a database, doing a calculation or just returning some text. The server returns the result to the client via an XML-RPC response. If an error occurs while the server is processing the request, an XML-RPC fault is returned to the client containing information about what went wrong.

XML-RPC Request

This is an example of an XML-RPC request for the location of an event named ‘Hello Kitty Expo’. The server method that the request is sent to is called ‘getLocationForEventName’ and it receives several parameters (in this case just one) as inputs for the method. In this example, the requested event name is received as a string value:

<?xml version="1.0"?>
<methodCall>
	<methodName>xmlrpctest.getLocationForEventName</methodName>
	<params>
		<param>
			<value><string>Hello Kitty Expo</string></value>
		</param>
	</params>
</methodCall>

XML-RPC Response

The server now has ‘Hello Kitty Expo’ as the input value for the method ‘getLocationForEventName’. That method could connect to a database and search through all events until it finds an event named ‘Hello Kitty Expo’. It could then get the value entered in the event’s ‘location’ field and return that value via an XML-RPC response. Similarly to an XML-RPC request, the response contains several parameters as the result. In this example, it only returns one parameter: a string value which is the location of the ‘Hello Kitty Expo’ event:

<?xml version="1.0"?>
<methodResponse>
	<params>
		<param>
			<value><string>Main Street Convention Centre</string></value>
		</param>
	</params>
</methodResponse>

XML-RPC Fault

If at any stage something goes wrong, the server can return an XML-RPC fault to the client. The fault contains an error code as well as a fault string which describes what went wrong. There are certain standardised fault codes that can be used, but generally the fault code can be a custom code that both the client and the server understand. If the ‘Hello Kitty Expo’ event cannot be found in the database using the XML-RPC request from above, an example of an XML-RPC fault could be as follows:

<?xml version="1.0"?>
<methodResponse>
	<fault>
		<value>
			<struct>
				<member>
					<name>faultCode</name>
					<value><int>123</int></value>
				</member>
				<member>
					<name>faultString</name>
					<value><string>Event not found</string></value>
				</member>
			</struct>
		</value>
	</fault>
</methodResponse>

The fault is returned as structured data also known as an associative array. A structure contains several members, each of which has a ‘name’ tag which is used to access the ‘value’ tag. To get the fault code, the client would access ‘faultCode’ which would return ‘123’. To get the fault string or error description, the client would access ‘faultString’ which would return ‘Event not found’.

Requests and responses can contain various datatypes, such as arrays, integers, associative arrays etc. The Wikipedia entry for XML-RPC has quite a nice table showing the various XML-RPC datatypes which you can use to build XML-RPC requests and responses.

On To The Meat!

Phew what a long introduction! At least you have a better understanding now of what XML-RPC is. Now we’re going to take a look at how you can use XML-RPC to establish communication between an iOS or Android app and a WordPress site.

Basic Assumptions

For this tutorial, I’m assuming you already have a working knowledge of the following:

  • running an Apache web server on your localhost using XAMPP
  • setting up an empty MySQL database
  • basic PHP coding
  • installing a standalone version of WordPress
  • very basic knowledge of how to build WordPress themes in PHP

WordPress Setup

You can download the latest version of WordPress directly from their site. Once you’ve completed the very quick and easy WordPress installation on your localhost, make sure you can actually get to the site. Don’t worry about what theme your test site is currently running, we’ll just be working with whichever theme comes default with the installation. When you first install WordPress, it comes with a default ‘Hello World!’ post and a ‘Sample’ page just to get you going. Don’t delete them, as we’re going to be using XML-RPC to access their content.

In our XML-RPC request example, we were sending a request to a custom method called ‘getLocationForEventName’. WordPress contains many XML-RPC methods that you can use to access various data on your site. You can see what methods are available in the XML-RPC WordPress API. We’re going to be creating our own XML-RPC method to use in our iOS and Android apps.

Creating Custom XML-RPC Methods In WordPress

In your currently activated theme’s folder, open ‘functions.php’. It will probably contain quite a lot of code that we’re not going to care about for this tutorial. So scroll right down to the bottom of your ‘functions.php’ file. That is where we’re going to be adding our code.

– Build Your Custom Method

XML-RPC method names should have a prefix in order to prevent method duplication. In our XML-RPC request example, the method name is ‘getLocationForEventName’ and the prefix is ‘xmlrpctest’. We’re going to create a custom XML-RPC method named ‘getPostTitle’ with a unique prefix called ‘xmlrpctest’. It has a parameter named ‘args’ which will contain whichever input is received from the client making the XML-RPC request. For our example, the method will receive a post’s ID as input and will return that post’s title. I know there are already WordPress XML-RPC methods that do this, but this is just a starting point for creating your own custom functionality that is beyond what the XML-RPC WordPress API can do.

As an example, the WooCommerce Events plugin generates unique tickets that each have their own check-in status. We created a custom XML-RPC method that the apps can use to update a specific ticket’s check-in status. It receives the ticket’s ID and new status as input data and then once the ticket’s status gets updated in the database, a response is returned containing information regarding whether or not the update was successful. There aren’t any built-in XML-RPC WordPress API methods that cater to this very specific requirement, which is why we had to build it ourselves.

To create your own custom XML-RPC method named ‘getPostTitle’, add the following code to your ‘functions.php’ file:

function xmlrpctest_getPostTitle($args)
{
    $postID = $args;
    
    $post = get_post($postID);
    
    return array("postID" => $postID, "postTitle" => $post->post_title);
}

The value sent through to the method as the $args parameter is the post ID which is stored in a $postID variable. Using the built-in WordPress method ‘get_post’, the post with ID $postID is stored in a $post variable. An associative array is returned to the client which contains the post ID value in the ‘postID’ field as well as the post’s title in the ‘postTitle’ field which we got by using the ‘post_title’ property of our $post object.

– Declare Your Custom XML-RPC Method

You need to tell WordPress about your custom XML-RPC method. You will create a custom method in your ‘functions.php’ file to do this. Add the following code beneath your custom XML-RPC method:

function xmlrpctest_new_xmlrpc_methods($methods)
{
    $methods['xmlrpctest.getPostTitle'] = 'xmlrpctest_getPostTitle';
    
    return $methods;   
}

This method adds all your custom XML-RPC methods to the list of available XML-RPC methods available to XML-RPC clients. It receives an array named ‘$methods’ which is the current list of available XML-RPC methods and adds your methods to that array. It then returns the updated list of XML-RPC methods.

– Add Your Custom XML-RPC Methods To WordPress

The last step is to tell WordPress to call your method for adding your custom XML-RPC methods to the current list of XML-RPC methods. Add the following code beneath what you’ve already added:

add_filter('xmlrpc_methods', 'xmlrpctest_new_xmlrpc_methods');

This line tells WordPress to send the current list of XML-RPC methods stored in ‘xmlrpc_methods’ to your custom method ‘xmlrpctest_new_xmlrpc_methods’ which adds your custom XML-RPC methods.

Building The iOS App

For this part of the tutorial, I’m assuming you have a basic working knowledge of iOS app development using Xcode and Objective-C. For this tutorial, I’ve coded a very basic app that we’re going to look at below. You can either download the sample iOS project or code it yourself from scratch.

It could be quite daunting to code your own XML-RPC framework for building properly structured XML-RPC requests and decoding XML-RPC responses to use in your app. There is a very nice lightweight XML-RPC encoder/decoder for iOS and OS X which you can download from GitHub. This is the framework we’ll be using for the iOS part of this tutorial.

– Basic Setup

Create a new Xcode project with a single view. Create a new group and call it something like ‘WPXMLRPC’. Add all the files contained within the WPXMLRPC folder of the extracted zip file you downloaded to the ‘WPXMLRPC’ group. Make sure you check the checkbox next to your target when adding the files and also check ‘Copy items if needed’ to make sure they get copied into your project’s folder.

Check the checkbox next to your target

Check the checkbox next to your target as well as ‘Copy items if needed’

Once you’ve imported the WPXMLRPC framework files into your project, your Project Navigator panel should look something like this:

Project Navigator panel

Project Navigator panel

If you immediately try to compile your app, you might get some warnings and some compile errors. There are a few changes we need to make before the app will compile successfully. In the ‘WPBase64Utils.h’ file, add the following line of code just above the interface declaration:

#import <Foundation/Foundation.h>

Open ‘WPXMLRPCEncoder.m’ and add the following code just above the ‘initWithMethod’ method implementation:

- (id)init
{
    return [self initWithMethod:nil andParameters:nil];
}

Open your target’s ‘Build Settings’ panel and then add the following value to the ‘Other Linker Flags’ setting:

-liconv

Your app should now compile, but won’t do anything. We first need to create the interface.

– Creating The Interface

Create a basic screen that has a button for interaction and a label to display results as follows:

Our test app's basic layout

Our test app’s basic layout

Once you’ve created and linked all your IBOutlets in the view controller’s header file, open your view controller’s implementation file. This is where we’re going to implement sending an XML-RPC request and doing something with the XML-RPC response that gets returned. I created an IBAction method called ‘getPostTitle’ and linked it with the button so that when you tap on the button, it will call this method and make an XML-RPC response. You can find the complete implementation of this method in the sample project which contains more code for error handling, but following is the basic implementation of what is required to send and receive data using XML-RPC.

– Create An XML-RPC Encoder

We want to send a post ID to our custom XML-RPC method ‘getPostTitle’ in order to retrieve that post’s title. We will first create an XML-RPC encoder object and initialise it with our custom method’s name as well specify an array of values to send as input data for the method:

WPXMLRPCEncoder *encoder = [[WPXMLRPCEncoder alloc] initWithMethod:@"xmlrpctest.getPostTitle" andParameters:[NSArray arrayWithObject:@"1"]];

In this case, the array only contains a single value: a string of the ID of the post that we want the title of. The encoder takes the input we provided and builds an properly structured XML-RPC request which will look something like this:

<?xml version="1.0"?>
<methodCall>
	<methodName>xmlrpctest.getPostTitle</methodName>
	<params>
		<param>
			<value><string>1</string></value>
		</param>
	</params>
</methodCall>

– Create A URL Request

Second, we want to create a URL request object and initialise it with the URL of the script on our site where we want to send the XML-RPC request to. All XML-RPC requests in WordPress must make POST requests to ‘xmlrpc.php’ which resides in the site’s root folder. We will set the XML-RPC encoder object that we created as the body of our URL request. Create the URL request as follows:

NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:@"http://localhost/Workspace/Projects/WP_XMLRPC_TEST/xmlrpc.php"] cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:10];
[request setHTTPMethod:@"POST"];
[request setHTTPBody:[encoder dataEncodedWithError:nil]];

– Send The XML-RPC Request And Do Something With The Response

As previously mentioned, the sample project has quite a bit more code specifically for error checking etc. but the basic implementation for sending the URL request and doing something with the response is as follows:

[[[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error)
{
    WPXMLRPCDecoder *decoder = [[WPXMLRPCDecoder alloc] initWithData:data];
    
    [self.responseLabel setText:[@"Post ID: " stringByAppendingFormat:@"%@, Post Title: %@", [[decoder object] objectForKey:@"postID"], [[decoder object] objectForKey:@"postTitle"]]];
}] resume];

When the response comes back, we create an XML-RPC decoder object and initialise it with the data received from the server. The server returns an XML-RPC response which looks something like this:

<?xml version="1.0" encoding="UTF-8"?>
<methodResponse>
	<params>
		<param>
			<value>
				<struct>
					<member>
						<name>postID</name>
						<value><string>1</string></value>
					</member>
					<member>
						<name>postTitle</name>
						<value><string>Hello world!</string></value>
					</member>
				</struct>
			</value>
		</param>
	</params>
</methodResponse>

The XML-RPC decoder contains an ‘object’ property which contains the decoded data received from the server. Since our custom XML-RPC method returns an associative array, the decoder object will also be an associative array. We can access the returned values by using the ‘objectForKey’ method on the decoder object for ‘postID’ and ‘postTitle’.

You can now compile and run your iOS app. If you tap on the button, it sends the XML-RPC request asynchronously to the server. After a short while, the response comes back and the response label’s text is updated to say ‘Post ID: 1, Post Title: Hello World!’.

The final app after receiving the XML-RPC response from the server

The final app after receiving the XML-RPC response from the server

Building The Android App

For this part of the tutorial, I’m assuming you have a basic working knowledge of Android app development using Android Studio and Java. For this tutorial, I’ve coded a very basic app that we’re going to look at below. You can either download the sample Android project or code it yourself from scratch.

We’re going to be using a lightweight XML-RPC Java library which you can download from GitHub.

– Basic Setup

Create a new Android project with a blank activity. Once you’ve downloaded the above mentioned XML-RPC Java library, extract the zip file and copy the ‘de’ folder from src->main->java into your project’s src->main->java folder and return to Android Studio. Your Project Window should look something like this:

The Android Studio Project Window once you've copied over the XML-RPC Java library

The Android Studio Project Window once you’ve copied over the XML-RPC Java library

Open your app’s manifest file and add the following permission allowing internet access just above your ‘application’ tag:

<uses-permission android:name="android.permission.INTERNET" />

There’s one change that we need to make to ‘DateTimeSerializer.java’ which can be found in the ‘serializer’ folder of the XML-RPC library. Change line 32 from:

return javax.xml.bind.DatatypeConverter.parseDateTime(value).getTime();

to:

return DATE_FORMATER.parse(value);

– Creating The Interface

Open your ‘activity_main.xml’ layout file and add a button and a text view which will be used to display the results as follows:

The basic interface for our Android app

The basic interface for our Android app

– Creating And Sending The XML-RPC Request

Open your ‘MainActivity.java’ file and add the following code to the ‘onCreate’ method beneath ‘setContentView(R.layout.activity_main)’. First we’re going to store a variable for the button as well as the text view:

final Button getPostTitleButton = (Button)findViewById(R.id.getPostTitleButton);
final TextView resultTextView = (TextView)findViewById(R.id.resultTextView);

Then we’re going to set the button’s ‘onClickListener’. If you look at the sample project, you will see it provides a bit more code for error handling. For the sake of simplicity, I’ve removed a lot of code just for this tutorial. The app will give errors saying that required error handling methods are missing etc. and won’t compile. Also, since the interface gets updated after an asynchronous task completes, you will need to run interface updates on the user interface thread, not the background thread. I’ve also removed this code just to simplify the code shown here. Without this code, there won’t be any compile or runtime errors. The interface just won’t update and you’ll spend hours trying to figure out why nothing is happening. If you want to compile and run your app, make sure it has all the code that is included in the sample project.

We’re going to create a new XMLRPCClient and initialise it with the URL that the requests should be sent to. You will notice it will be the same URL as the one we used in the iOS app. Then we’re going to start an asynchronous call by providing various parameters. For the first parameter we’re going to create a new XMLRPCCallback object so that we can do something once the server responds with the result of our XML-RPC request. The second parameter is the method name that should be called. After the second parameter, any additional parameters will each be used as separate input data for the method. If there is just one additional parameter, then the $args variable in our WordPress XML-RPC method will contain just that value. If we add two or more parameters, then the $args variable will be an array of values.

The simplified implementation for creating the XML-RPC request is as follows:

final XMLRPCClient client = new XMLRPCClient(new URL("http://localhost/Workspace/Projects/WP_XMLRPC_TEST/xmlrpc.php"));

client.callAsync(new XMLRPCCallback()
{
	@Override
	public void onResponse(long id, Object result)
	{
		Map postData = (Map)result;

		resultTextView.setText("Post ID: " + postData.get("postID") + ", Post Title: " + postData.get("postTitle"));
	}
}, "xmlrpctest.getPostTitle", 1);

When the server responds, it returns an Object called ‘result’. We know that our custom XML-RPC method returns an associative array, so we’re going to create a Map object called ‘postData’ and set it to the ‘result’ object which gets casted to a Map object. We can then use the ‘get’ method on the postData Map object to retrieve the value stored for key ‘postID’ and ‘postTitle’.

You can now compile and run your Android app. If you tap on the button, it sends the XML-RPC request asynchronously to the server. After a short while, the response comes back and the response text view is updated to say ‘Post ID: 1, Post Title: Hello World!’.

The final app after receiving the XML-RPC response from the server

The final app after receiving the XML-RPC response from the server

Conclusion

What a mouth full! I’m sure the word ‘XML-RPC’ sounds funny now if you say it out loud. If you’ve managed to work your way through this entire tutorial, you should now be able to create your own weird and wonderful custom XML-RPC methods in WordPress, send requests with input data to those methods from your iOS or Android app, and do something breathtakingly incredible with the results. In case you missed it, you can download, compile and run the sample projects I made for both iOS and Android. Please enjoy!