Creating a Simple iPhone Web Service in Django

While working on an iPhone app that needs to communicate with a Django server, Kyle and I discovered Python’s awesome plistlib, which can convert Python objects to Apple’s XML plist format.

Server-Side

import plistlib
import datetime
from django.http import HttpResponse

def myview(request):
    data = {
        'Username': 'someuser',
        'CurrentTime': datetime.datetime.now(),
        'Score': 543
    }
    plist = plistlib.writePlistToString(data)
    return HttpResponse(plist, mimetype='application/plist+xml')

When your iPhone app requests the URL connected to this view, it’ll receive XML that looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" 
  "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>CurrentTime</key>
	<date>2010-09-01T14:56:08Z</date>
	<key>Score</key>
	<integer>543</integer>
	<key>Username</key>
	<string>someuser</string>
</dict>
</plist>

Client-Side

After getting the contents from that URL (if you’re not already, you should be using the excellent ASIHTTPRequest library), you can convert it into an NSDictionary with NSPropertyListSerialization.

In fact, none of this Objective-C code is iPhone-specific: this same technique will work on iPad and Mac OS X.

- (void)requestFinished:(ASIHttpRequest *)request {
    NSData *downloadedData = [request responseData];
    NSDictionary *data = [NSPropertyListSerialization propertyListWithData:downloadedData 
                                                                   options:0
                                                                    format:kCFPropertyListXMLFormat_v1_0
                                                                     error:&error];
    NSString *username = [data objectForKey:@"Username"];
    NSDate *currentTime = [data objectForKey:@"CurrentTime"];
    NSInteger score = [[data objectForKey:@"Score"] integerValue];
}

Caveats

plists are relatively big. The XML above weighs in at 347 bytes; the same data serialized as JSON is a much slimmer 91 bytes. Especially over AT&T’s 3G network, that size difference can be noticeable. The downside to using JSON is that Apple doesn’t provide a JSON parser in the iOS SDK; you’ll have to write your own or include someone else’s.

Also worth noting is that the plist format is very Apple-specific. I haven’t looked at the Android or BlackBerry SDKs, but I would guess that they don’t have any utilities to parse plists. If you plan on using the same web service across multiple clients, this might affect your decision about how to serialize the data.

Those points aside, using plistlib is an easy way to get started with server-to-iPhone communication without needing to bring in third-party code.

Advertisements

About this entry