Data-Driven iPhone Apps with Property Lists and PHP

By Aaron Dunnington · December 16, 2009

Binary Load Lifter When driving iPhone apps with data from the cloud, the device's underlying connection speed is often a potential performance bottleneck. As devices consume increasingly larger sets of data over the air, an app's ability to provide a smooth experience can be constrained. Thus, when selecting payload formats or compression techniques, service aware mobile apps can really benefit from a healthy respect for just how much an EDGE or 3G connection can hose your transfer rates.

One way to add a performance optimization to the payload format consumed by data driven iPhone apps is through Property Lists. Property Lists provide a great mechanism for iPhone apps to transparently marshal data in and out of an app using either XML or binary formats.

As great as XML is for exposing data to a wide range of clients, it is verbose by design, and often bloats wire payloads in favor of interoperability. If you can afford to introduce a little coupling of your mobile app to your service, the binary serialization format of Property Lists may potentially boost perf 5 to 20 times over text based Property Lists. Though, even the XML based Property List schema arguably would add some coupling to the Mac platform. On the other hand, if you'd rather give up the seamless interaction the Property List APIs have with native data types on the iPhone, it would be interesting to see how a minimalistic POX based format performs against binary Property Lists.

Nevertheless, there are a number of options for exposing Property Lists on the server depending on your language. I've seen Property List implementations for Python, Perl, and PHP. If you're running OSX on the server, of course both Cocoa and Core Foundation offer Property List APIs; or, you could run plutil from the shell. Lastly, there's always parsing the raw bytes if that's more your bag. Though, unless you really want to understand Apple's binary serialization format for Property Lists by parsing it yourself, the Cocoa, Core Foundation, plutil, PHP, and Perl implementations are the options I've seen thus far that offer binary support.

The CFPropertyList project provides a Property List implementation for PHP. Here's a simple Zend controller that exposes a list of entries using CFPropertyList.


<?php

require_once 'CFPropertyList/CFPropertyList.php';
require_once 'models/Entry.php';

class BlogController extends Zend_Controller_Action
{
    public function init()
    {
        $this->_helper->viewRenderer->setNoRender();
        $this->_helper->layout->disableLayout();
    }

    public function indexAction()
    {
        $table = new Entry();

        $select = $table->select();
        $rows = $table->fetchAll($select);

        $plist = $this->createPropertyList($rows);

        $this->getResponse()->setHttpResponseCode(200);
        $this->getResponse()->setHeader('Content-Type', 'application/octet-stream', true);
        $this->getResponse()->setBody($plist->toBinary());
    }
}

Here, we grab some entries from the database, then call createPropertyList (which we'll write next) with the results, and lastly serialize the response in the binary format by calling the toBinary method on the returned plist object. Now, let's generate the property list from our data set below.


private function createPropertyList($rows)
{
    $entries = new CFArray();
    foreach ($rows as $row)
    {
        $entry = new CFDictionary();
        $entry->add('id', new CFNumber($row->entry_id));
        $entry->add('title', new CFString($row->title));
        $entry->add('author', new CFString($row->author));
        $entry->add('summary', new CFString($row->summary));
        $entries->add($entry);
    }

    $d = new CFDictionary();
    $d->add('feed', $entries);

    $plist = new CFPropertyList();
    $plist->add($d);

    return $plist;
}

This method iterates over the result set while creating corresponding Property List structures. The CFPropertyList PHP library provides type wrappers for the corresponding property list data type, for example, CFDictionary, CFArray, CFNumber, and CFString in the above snippet. This function produces a Property List with a top level CFDictionary that has one item named "feed". The value of the "feed" item is a CFArray which contains a CFDictionary object for each entry.

Then, on the client, here's a quick look at how to consume the property list based service. Here, we make a remote call to the service, and turn the resulting NSData into a Property List to print out the title of each entry. The remote call in this code blocks with the invocation of sendSynchronousRequest:returningResponse:error: for the sake of brevity; though, in practice, processing the request asynchronously with NSURLConnection may be more appropriate.


NSURL *url = [NSURL URLWithString:@"http://localhost/blog"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];

NSData *data = [NSURLConnection 
                            sendSynchronousRequest:request
                            returningResponse:&response
                            error:&error];

id pList = [NSPropertyListSerialization
                   propertyListFromData:data
                   mutabilityOption:NSPropertyListImmutable
                   format:&format
                   errorDescription:&errorStr];

NSDictionary *d = (NSDictionary *)pList;
NSArray *entries = (NSArray *)[d objectForKey:@"feed"];

for (NSDictionary *entry in entries) {
    NSLog(@"Title: %@", [entry objectForKey:@"title"]);
}


CFPropertyList's baked in support for binary is cool. It provides a great way for PHP services to shrink the wire payloads compared to text based formats in order to serve data hungry iPhone apps over constrained connection speeds. Given the growth in machine readable formats across service offerings over the past couple years, coupled with the huge demand for data centric iPhone apps, it'd be interesting to see how common the various hydration approaches are in the market today.

I Gotta Have More Cowbell

By Aaron Dunnington · December 5, 2009

More Cowbell Blogging is quite an amazing thing. In software, I have always found a ton of value in the material generated by the dedicated devs that continually contribute their work to the community through blogging.

While blogging was blowing it up, I attempted, but only materialized a measly couple of posts.

Fast forward a bit, the blogosphere all grows up, and I think I'll give it another crack. Hopefully this time with more cowbell.

This blog runs on Google App Engine and Tornado. The app itself is based on Bret Taylor's work targeting GAE. Thanks to Bret for the contribution to the community!

AJAX: Great Stuff, Why Now?

By Aaron Dunnington · September 4, 2005

Those into web applications have no doubt heard the buzz of late on Asynchronous JavaScript and XML (AJAX), an approach to web development that focuses on harnessing the existing client side processing capabilities of modern browsers. In short, a larger portion of web application code, typically JavaScript, can be downloaded to and executed on the client machine. Further, the client code leverages the XMLHttpRequest object built in to most browser engines to communicate with the server in the background using XML and HTTP.

The most compelling reason for using the AJAX technique is that it enables a more fluid user experience. In other words, the user is not constantly interrupted to jump to a new page. Thus, with the understanding that client processing is far less expensive than network communication, the AJAX approach allows web applications to behave more like desktop applications.

As more and more code moves from server to client, however, intellectual property vulnerabilities may become an issue. Of course, this is very specific to the organization responsible for the application. If the organization is driving an open source effort or primarily focused on providing a service that is coupled to hosting infrastructure, exposing the client application may not be as much of an issue. On the other hand, if the corporate advantage resides in the client application, depending on customer audience, intellectual property exposures should be evaluated. Preventative measures can be taken through JavaScript obfuscation and potentially the future development of JavaScript security standards. Further, for very large applications, the amount of code downloaded to the client machine may pose interesting performance challenges. Could we use AJAX precepts to download more AJAX precepts?

Overall, I am very excited to see the improvement of the user experience in web applications. One parting question: what has changed recently to cause the flurry of AJAX activity? Was it the acronym itself? These technologies have been around since 1998. Why haven't application infrastructures and tools been maturing over the years? Possibly more importantly, is there a technology out there now that will raise similar questions seven years from now?

©2010 aaron dunnington - about - creative commons license