Squiz Matrix as a XML Datasource in iOS

Sun, Jun. 12, 2011

The great thing about using a CMS like Squiz Matrix is its flexibility. So when we decided to build a Pacific Union College iOS app it was a snap to get Matrix working as the datasource.

I decided to use XML to provide the data (primarily from asset listings), but first I needed to do some proper setup and gather the tools that I would need.

The reason I didn't use JSON was, in Squiz Matrix it isn't always possible to create valid JSON, which means removing the trailing comma on a listing. It is possible on asset listings, but not on things like a Calendar Page, which was essential to our app.

The Parse File

In Squiz Matrix I needed to create a separate design file that would be applied to all of my assets that were acting as datasources, for this I used the following format:

<MySource_PRINT id_name="__global__" var="content_type" content_type="text/xml; charset=utf-8" />
<?xml version="1.0" encoding="UTF-8"?>
<MySource_area id_name="body" design_area="body" />

Example Asset Listing

For most of the tabs in the Pacific Union College app an asset listing is used.

  • Webpaths

Setting up the asset listing that would serve as the datasource was pretty straight forward. For a simple listing such as the Current News, I used the following setup:

Page Contents


Page Format


Parsing the XML in Objective-C

When I started looking for an XML parser I was overwhelmed by the number of articles and blog posts about which parser was the best. There were comparisons between NSXMLParser and libxml2, as well as many people talking about KissXML. All of these were fair solutions that would work well, but I wanted something very lightweight that was easy to use. After searching around a bit, I found XML Reader by Troy Brant. It was a very simple XML Parser that turned the parsed xml into an NSDictionary object which is exactly what I wanted.

Using the parser is very simple, all you have to do it provide it with an XML string and an NSError object:

NSError *parseError = nil;
NSDictionary *dict = [XMLReader dictionaryForXMLString:xmlStr error:&parseError];

Once the parser spit out the NSDictionary I simply needed to loop through it in order to get the data that I wanted.

NSError *parseError = nil;
NSDictionary *dict = [XMLReader dictionaryForXMLString:xmlStr error:&parseError];
NSDictionary *newDict = [[dict objectForKey:@"body"] objectForKey:@"item"];

// Check if we have one or more results
if ([newDict isKindOfClass:[NSArray class]]) {
	for (id theKey in newDict) {
		NSString *title = [util cleanString:[[theKey objectForKey:@"title"] objectForKey:@"text"]];
		NSString *sub = [util cleanString:[[theKey objectForKey:@"sub"] objectForKey:@"text"]];
		NSString *assetId = [util cleanString:[[theKey objectForKey:@"id"] objectForKey:@"text"]];
		NSLog(@"%@ - ID: %@", title, assetId);
	}//end for
} else {
	// Do somethign else if not an array

Things To Think About

Getting the data from a URL and then parsing it can take some time. Not a huge amount of time, maybe a second or two depending on how fast your server is and how large your file is. But you don't want your users having their UI locked up until the data loads. So, in this case it is a good idea to load the data in the background:

 * The initial call to the datasource
 * @version $Revision: 0.1
- (void)initDataSource {
	[self performSelectorInBackground:@selector(callDataSourceWithId:) withObject:@""];

Caching on the device is another thing that needs to be considered if your datasource comes from some URL. If users don't have an internet connection they still want to browse the app. For the Pacific Union College app we cache all datasource XML files and use those files if the user is offline.

Nicholas Hubbard

Add Comment