The iPhone was arguably the hottest development platform of 2008 and likely to get only hotter in 2009.
The natural scalability that you get with AWS and the Internet-connectivity that the iPhone has makes the two an ideal pair.
That being the case, I was wondering what it would take to use Amazon Web Services in an iPhone application. The first service I decided to tackle was SimpleDb.
It’s really not that important for this post, but the context of my experiment is snow reports - it’s winter time in the Northwest so I thought I would use a SimpleDb domain as sort of a clearing house for snow reports from the various ski resorts in the area. My iPhone application would pull down data from this domain and display it in a table.
The decision I had was how to access SimpleDb. The Amazon Web Services all expose themselves through a combination of REST, Query and SOAP.
Accessing SimpleDb - SOAP or REST?
SOAP is a great option when you’re using .NET, Java or any other language that has a nice SOAP stack. The added advantage of SOAP is that you can use it with WS-Security, which means you can authenticate with a X.509 certificate, rather than passing around your secret and key.
But, the iPhone doesn’t really have a mature SOAP implementation. I did a little bit of searching and I found some experimental stuff, but nothing that I felt comfortable using. I’m pretty much a beginner with Objective-C and iPhone development.
I considered writing my own minimal SOAP stack, but that would involve creating the XML requests and parsing the XML response. Regardless of what method I use, I would have to parse the XML response. However, if I use REST, I am just putting together a URL request, so I can save myself 1/2 of the XML work. So, my choice was to use the SimpleDb REST API.
REST Authentication
This is actually where I ran into the most trouble. When using REST with Amazon Web Services, you have to pass along a authentication signature. Creating this signature is in concept well described by the Amazon documentation - it is just a matter of sorting your query parameters, capturing a time stamp and using your AWS secret as the key in a HMAC-SHA hash function.
The devil is in the details however. Let’s start from the beginning. The first thing I did was use a NSMutableDictionary to store my parameter values as you can see below.

Parameter Values
The snippet of code shown is actually for any generic SimpleDb call.
The parameters being added are required for all of the SimpleDb API calls.
After I’ve added these required parameters, I just need to add the parameters that are specific to the method that I’m calling.
Once that is done, to make the signature, the first step is to condense these parameters into a canonical form. The Amazon documentation does a more complete job of explaining this, but the general idea is that Amazon will take your parameters, your key, your time stamp and basically run the same hash algorithm. If the hashes are the same, then you are authenticated.
The canonical form is pretty straightforward, it is basically your parameters (both names and values) concatenated into a string. The parameters are in ascending order by their names first.

The NSMutableDictionary class has a nice method (or I guess message in Objective-C parlance) that does the sort for me - I can even indicate that I want a case insensitive comparison.
Getting this canonical string correct is absolutely crucial. If you make a mistake here, then your hash will be wrong and you will not be authenticated. I found what really helped was using the Amazon JavaScript ScratchPad for SimpleDb. This tool has a correct implementation of the signature creation algorithm, and there is an option to conveniently show the canonical string.

Having a reference implementation really helped to make sure that I was creating the right canonical string. You’ll notice that this scratch pad also has an option to see the signed URL. This helpful, but this value is not synchronized with the time stamp that was generated for the canonical string.
HMAC-SHA1 on the iPhone
Once I was able to generate canonical string, it was time to generate the hash value for it. This was actually the hardest part for me. Most languages like .NET, PHP, Java, etc have good encryption libraries, so generating this hash is trivial. On Mac OS X, I believe most people use the Open SSL library to do this type of work. However, Open SSL was not ported to the iPhone SDK. Apparently it was there in the early betas, but it was pulled out at some point.

I ended up making do with the CommonCrypto framework that is available for the iPhone.
Please see ‘Part 2’ for more details about this implementation…
March 31st, 2009 at 7:57 am
[...] Here is a good tutorial for connecting your iphone app to Amazon Simple DB service. SimpleDb and the iPhone - Part 1 [...]
April 8th, 2009 at 11:24 pm
The style of writing is quite familiar to me. Have you written guest posts for other blogs?
April 9th, 2009 at 7:23 am
Actually I haven’t done other posts - I would be happy to, but the opportunity hasn’t come up.