Storing High Scores in Amazon SimpleDB

Storing High Scores in Amazon SimpleDB using the AWS SDK for iOS and the AWS SDK for Android


Submitted By: Glenn@
AWS Products Used: iOS, Android, Amazon SimpleDB
Language(s): Objective-C, Java
Created On: November 22, 2011


Version 2 of the AWS Mobile SDK
  • This article and sample apply to Version 1 of the AWS Mobile SDK. If you are building new apps, we recommend you use Version 2. For details, please visit the AWS Mobile SDK page.
  • This content is being maintained for historical reference.

Storing High Scores in Amazon SimpleDB using the AWS SDK for iOS and the AWS SDK for Android

This article highlights the benefits of connecting mobile devices to the cloud while also presenting an Amazon SimpleDB use case. Amazon SimpleDB is a highly available, flexible, and scalable non-relational data store that offloads the work of database administration. The mobile application described here demonstrates how to store a high score list or leader board in SimpleDB. The application enables the user to view the high scores sorted by name or score, add and remove scores, and more. This article shows sample code for both the iOS and Android platforms. The complete sample code and project files are included in the AWS SDKs for these mobile platforms. Links to the SDKs are available at the end of this article.

To use the AWS SDK for iOS or the AWS SDK for Android, you will need your AWS credentials, that is, your Access Key ID and Secret Access Key. If you haven't already signed up for Amazon Web Services (AWS), you will need to do that first to get your AWS credentials. You can sign up for AWS here. After you have signed up, you can retrieve your credentials at this page.

Overview

SimpleDB stores data in domains. Each domain is a collection of items and each item is a collection of attribute/value pairs. For the app, we create a single domain to store our high score list. Each item in the domain represents an individual player. The items will have two attributes, the player's name and their score. Items also have a unique identifier called the item name that, in this case, is equal to the player's name. Storing the player's name and score as item attributes enables us to sort the items by name or score.

The app demonstrates how to add and remove individual players, sort the scores by player name or score, and retrieve a single item from the domain. The app also demonstrates how to create and delete SimpleDB domains.

Creating a SimpleDB Client

Making requests to SimpleDB requires a client. Creating a SimpleDB client for iOS or Android is shown below.

  • iOS

AmazonSimpleDBClient sdbClient = [[AmazonSimpleDBClient alloc] initWithAccessKey:ACCESS_KEY_ID withSecretKey:SECRET_KEY];
  • Android

AWSCredentials credentials = new BasicAWSCredentials( ACCESS_KEY_ID, SECRET_KEY );
AmazonSimpleDBClient sdbClient = new AmazonSimpleDBClient( credentials);

High Score List Creation (Domain Creation)

Individual player scores are stored as items in a SimpleDB domain. This requires that we create the domain first. Using the appropriate client that we created above, we can use the following code to create the domain.

  • iOS

SimpleDBCreateDomainRequest *createDomain = [[[SimpleDBCreateDomainRequest alloc] initWithDomainName:HIGH_SCORE_DOMAIN] autorelease]; 
[sdbClient createDomain:createDomain];
  • Android

CreateDomainRequest cdr = new CreateDomainRequest( HIGH_SCORES_DOMAIN );
sdbClient.createDomain( cdr );

Add Score (Item Creation)

An item is a collection of attribute/value pairs. For our items, we create two attributes, one for the player's name and one for the player's score. These are added to a request along with an item name in order to create the item. Because a player appears at most only once on the high score list, we use the player's name to uniquely identify each item. All data in SimpleDB are stored as strings, therefore numbers must be zero padded if you want to sort them properly.

  • iOS

The AWS SDK for iOS does not include a utility to pad numbers. A simple utility is included in the full sample code.

NSString *paddedScore = [self getPaddedScore:score];

SimpleDBReplaceableAttribute *playerAttribute = [[[SimpleDBReplaceableAttribute alloc] initWithName:@"player" andValue:player andReplace:YES] autorelease];
SimpleDBReplaceableAttribute *scoreAttribute = [[[SimpleDBReplaceableAttribute alloc] initWithName:@"score" andValue:paddedScore andReplace:YES] autorelease];

NSMutableArray *attributes = [[[NSMutableArray alloc] initWithCapacity:2] autorelease];
[attributes addObject:playerAttribute];
[attributes addObject:scoreAttribute];

SimpleDBPutAttributesRequest *putAttributesRequest = [[[SimpleDBPutAttributesRequest alloc] initWithDomainName:HIGH_SCORE_DOMAIN andItemName:player andAttributes:attributes] autorelease];
[sdbClient putAttributes:putAttributesRequest];
  • Android

The AWS SDK for Android includes a utility to pad numbers, used below.

String paddedScore = SimpleDBUtils.encodeZeroPadding( score, 10 );
		
ReplaceableAttribute playerAttribute = new ReplaceableAttribute( PLAYER_ATTRIBUTE, player, Boolean.TRUE );
ReplaceableAttribute scoreAttribute = new ReplaceableAttribute( SCORE_ATTRIBUTE, paddedScore, Boolean.TRUE );
		
List attrs = new ArrayList(2);
attrs.add( playerAttribute );
attrs.add( scoreAttribute );
		
PutAttributesRequest par = new PutAttributesRequest( HIGH_SCORES_DOMAIN, player, attrs);		
sdbClient.putAttributes( par );

Remove Score (Item Deletion)

Removing a score from the list simply means deleting an item from the domain. Deleting an item requires the unique name for the item you wish to delete. In SimpleDB, deleting an item is done by removing all the attributes from that item. Invoking deleteAttributes with no specified attributes removes all the attributes by default.

  • iOS

SimpleDBDeleteAttributesRequest *deleteItem = [[[SimpleDBDeleteAttributesRequest alloc] initWithDomainName:HIGH_SCORE_DOMAIN andItemName:player] autorelease];
[sdbClient deleteAttributes:deleteItem];
  • Android

DeleteAttributesRequest dar = new DeleteAttributesRequest( HIGH_SCORES_DOMAIN, player );
sdbClient.deleteAttributes( dar );

Player View (Getting an Item)

Knowing an item's name makes it easy to find the item. This next snippet shows how to get all the attributes for an item using the item name. Note that items may contain many attributes and values.

  • iOS

SimpleDBGetAttributesRequest *gar = [[SimpleDBGetAttributesRequest alloc] initWithDomainName:HIGH_SCORE_DOMAIN andItemName:player];
SimpleDBGetAttributesResponse *response = [sdbClient getAttributes:gar];
  • Android

GetAttributesRequest gar = new GetAttributesRequest( HIGH_SCORES_DOMAIN, player );
GetAttributesResult response = sdbClient.getAttributes(gar);

List View and Sorting (Select)

Getting a collection of scores, sorted by player name or the score itself requires the use of a select request. A select request uses a simple query language to determine which items to match and what data to return and how. Select requests are paginated because the number of items matching the query can be large. Therefore, select requests return a next token that enables you to "page" through the data in an ordered fashion. The code here shows how to return items ordered by score from highest to lowest. Only the score and player attributes are returned. More information regarding SimpleDB queries can be found in a reference article linked below.

  • iOS

SimpleDBSelectRequest *selectRequest = [[[SimpleDBSelectRequest alloc] initWithSelectExpression:@"select player, score from HighScores where score >= '0' order by score desc"] autorelease];
selectRequest.consistentRead = YES;
selectRequest.nextToken = nextToken;

SimpleDBSelectResponse *selectResponse = [sdbClient select:selectRequest];
nextToken = selectResponse.nextToken;
  • Android

SelectRequest selectRequest = new SelectRequest( "select player, score from HighScores where score >= '0' order by score desc" ).withConsistentRead( true );
selectRequest.setNextToken( nextToken );
		
SelectResult response = sdbClient.select( selectRequest );
nextToken = response.getNextToken();

List Deletion (Domain Deletion)

The quickest and easiest way to remove the entire high score list would be to delete the SimpleDB domain. Here is how to do that.

  • iOS

SimpleDBDeleteDomainRequest *deleteDomain = [[[SimpleDBDeleteDomainRequest alloc] initWithDomainName:HIGH_SCORE_DOMAIN] autorelease]; 
[sdbClient deleteDomain:deleteDomain];
  • Android

DeleteDomainRequest ddr = new DeleteDomainRequest( HIGH_SCORES_DOMAIN );
sdbClient.deleteDomain(ddr);

Conclusion

The code in this article demonstrates how to use Amazon SimpleDB as an indexed storage device for your mobile application. The complete sample app is included as part of the AWS mobile SDKs, which are linked below. The reference section also contains a link to a SimpleDB article which discusses writing queries for SimpleDB in detail.

References

A sample app that includes this code is hosted in our samples repositories on GitHub:

For more information about using AWS credentials with mobile applications see the following article:

Want to learn more?

To learn about mobile development best practices, follow our AWS Mobile Development Blog. You can also ask questions or post comments in the Mobile Development Forum about this or any other topic related to mobile development with AWS.