IRL Gaming | In Real Life Gaming | Zombie Hood available now for iPhone

Control your virtual life with your real life. Zombie Hood available now for iPhone

18 Nov 2011 Posted by Dan

NoSQL on iOS with Titanium Appcelerator? No worries!

If you’ve spent any time building data driven applications on the Titanium Appcelerator platform you’ve probably had to deal with SQLite.

SQL databases (and particularly SQLite) are a great solution, but they can become a real pain when you’re prototyping or rapidly iterating the design of your application. Maintaining complicated databases schemas, figuring out indexes, and writing ugly embedded SQL queries can really slow down the pace your team works at and make your code difficult to maintain.

During the development of Zombie Hood this became a major issue for us as a team. SQLite proved to be unsuitable for a number of reasons:

  • It was slow and difficult to constantly modify, re-index and deploy a new schema every time we changed the application or added a new feature
  • Migrating data between versions of the app became very difficult
  • Our data wasn’t secure – users with jail broken phones could basically change whatever they wanted whenever they wanted (and they did)
  • Translating between tabular data and objects in JavaScript turned out to be fairly inefficient even with our own custom ORM libraries
  • Moving data between our MongoDB driven API and our SQLite driven application was clunky and error prone
  • Maintaining large embedded SQL queries turned out to be a maintenance nightmare in JavaScript

After version 1.2 of the app went live it became clear that SQLite was a bad fit for us. After researching better solutions we finally decided to build our own NoSQL data management solution. It works great, we love it, and now it’s available on the Open Mobile Marketplace for iOS developers.

If you’re comfortable working with JSON, and you’ve had a quick look at MongoDB then you’re already up to speed on how this module works. We designed the system from the ground up to be:

  • Secure – all data committed to and read from disk is signed so that it can’t be tampered with by users
  • File Based – we didn’t want to run a server on the handset, so all data committed to storage is encoded as JSON and stored in flat files. This also means that all your data is portable
  • MongoDB Compatible – we constantly shift data between our API and the user’s handset so JSONDB generates unique BSON Object Ids and MongoDate objects in accordance with the specification.
  • Flexible – JSONDB had to allow us to combine query expressions, conditional expressions and mutation expressions in any order. We also implemented the DBRef spec to allow references to objects between collections along with dynamic object reference resolution.
  • Single Context – single execution context apps are the only way to go in Appcelerator, so while JSONDB isn’t thread safe it runs in the same execution context as the app. This makes it lightning fast to perform queries and updates.
  • Light Weight – the entire NoSQL engine comes in at 600 lines of JavaScript code
  • Simple – we wanted to get rid of ugly SQL queries and make everything object based, very similar to the way MongoDB queries work
  • Easy – no schema, no indexes, no complicated SQL. Just objects. That’s how JavaScript should be.
  • Geo-spatial Query Support – we needed to be able to perform geo-spatial queries on our data-set on the handset

So, let’s imagine an application where the user can add contacts to an address book, along with cartesian coordinates so that the records can be displayed on a map. A contact record might have a nickname, a full name, an email address, a phone number, and an address. We’ll also include some cartesian coordinates.

We could create a contacts collection and add a record as follows:

var json = require("com.irlgaming.jsondb");
var collection = json.factory("contacts");{
full_name:"John Smith",
address:"13 Dobney Avenue, Wagga Wagga, NSW, Australia, 2650",
loc:{lat:-35.110, lng:147.377},
timestamp:(new Date()).getTime()

This creates a new contacts collection (or loads an existing one), creates a new record and commits it to storage. You would plug this into your contact management GUI so users can add contacts. Let’s imagine that your user has added a couple of hundred contacts to their collection and want to search through them to find John Smith based on his name:

var o = collection.find({name:/smith/i}, {$limit:1, $sort:{timestamp:1}});

This will return the first object with a name property matching “smith” ordered by creation date from oldest to newest. This is a pretty simple example, so what if the user wanted to retrieve a list of all contacts near them within a 1km radius ordered by nickname alphabetically?

var o = collection.find({loc:{$within:[[5, 5], 0.2]}}, {$sort:{nickname:2}});
for(var i=0; i[i]);

Another example might be the user wanting to update all of John Smith’s records to set the phone number to 9090909 if the records were added less than a week ago:

collection.update({name:'John Smith', timestamp:{$gte:((new Date()).getTime() - 604800000)}}, {$set:{phone:9090909}});

Finally, if the user wanted to remove all records from their contact list that didn’t have phone numbers:


These are really just a few very simple examples of just how powerful this module is. If you’d like to know more check out the product page on the Open Mobile Marketplace or drop us a line at

This entry was posted in IRL Blog, IRL Development. Bookmark the permalink.

3 Responses to NoSQL on iOS with Titanium Appcelerator? No worries!

  1. Jeff Haynie says:

    This is awesome!

  2. Leo says:

    This is pretty awesome. The security alone I think is worth it.

  3. Pingback: Featured app – Zombie Hood - Learning Appcelerator Titanium

Leave a Reply

Your email address will not be published. Required fields are marked *


You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Check out Zombie Hood!