Releasing Tristania fan app
We are proud to announce the release of our latest creation; the official app for the magnificent metal band Tristania!
Features:
To get a feel for the app, please peruse the screenshots below:
With the app you can follow Tristania's various digital presences such as the official homepage, Twitter, Facebook, YouTube, gallery etc, from one convenient place. You'll also find a comprehensive discography section with lyrics and band comments, as well as other related band information. Some discussion on the included features can be found in this blog post.
If you're a Tristania fan you probably won't want to read any further, as this blog focuses on the technical side of things. Instead you might want to head on over to this thread in the official forum, where you can discuss the app, tell us of bugs, etc. But, if you're a nerd, read on!
Used tools:
Although it is unlikely that the average reader of this blog is unfamiliar with any of these JS-Ninja weaponry, here's a quick rundown of the tools used when building the Tristania app. If any of the below is missing from your toolbox, definitely rectify right away!
Titanium
As usual we built the application using Titanium, so that we can program in the language we know and love (JavaScript, as opposed to Objective C), yet still deploy it as a native application.
Although little brother has extensive experience with Titanium by now, this was my first "serious" deep-dive into the framework. Here are some of the lessons learnt during that journey:
- The emulator is not to be trusted, you need to make regular sanity checks on an actual device. In particular, what the emulator will not emulate is lag when a table / webview / somedetailedobject is rendered on the phone. Several times we had to refactor our code, when real-life tests revealed a certain solution to be too slow, in spite of split-second rendering in the emulator.
- Frequently delete everything in the build directory. Yes, this means that you have to perform a full rebuild to test the next iteration, which some extra takes time. But you will save yourself from hugely annoying bug hunts caused by Titanium erroneously keeping old settings in the build. Take extra care to flush build before building to the device, and definitely flush thrice before packaging for upload to app store.
- Just ignore the official documentation completely. It is nowhere near complete, and full of half-truths and outright lies. Rely instead on the Kitchen Sink code. While not exactly a shining example of best practices, it has working examples of pretty much everything. When that fails, check the source code of Titanium itself. Also the FAQ discussion on the official homepage is a good resource.
- Titanium is still a beta-ish platform, and sometimes the boat will be rocking for no fault of yours. But, it is getting more stable by each release, and being able to code native apps in beautiful JavaScript is worth the frustration.
- The API is very low-level, as it should be. So for a large application you definitely need some kind of library to keep you sane, lest you have to type out lots of very verbose code everytime you want to create some non-trivial element. We adressed this through a little library of our own, which is slowly making its way to maturity. Especially with the added investment just announced today, things are only going to get better!
Now, misunderstand me correctly - in spite of the whiny tone of the above notes, I still feel that Titanium is a remarkable framework, and that it is definitely heading in the right direction.
YQL
Yahoo's web service to transform any online data into beautiful JSON is nothing short of brilliant. I already sang the praise of this service in the in-progress post, so shall not reiterate that here. The main point for us was to be able to isolate fragile scraping logic outside the application, in a YQL OpenTable. Should the site we scrape change its markup, we just update the table, and all apps will instantly work again. Also, being able to pass pure JSON back to the app is wonderful, making for a beautiful separation of concerns.
CouchOne
This is another road that little brother paved for me, as he has used CouchDB in both Golingo and Systemet. For me, however, it was a completely new experience.
What's special about CouchDB is not just that it's all JavaScript emitting JSON (which in and of itself is really cool), but it is a (for me) whole new way to think about data. The veterans among you are probably wrinkling your noses over us youngsters never having heard of MapReduce before, but somehow I've managed to completely miss this database approach. In a MapReduce database, data isn't organized in tables. Instead it is all "documents", meaning a simple object of key-value pairs. Here, for instance, is a user document from the Tristania database:
Since there are no tables, you cannot simply "SELECT * FROM Users". Instead, you program a "view", using JavaScript. Every document will be sent as an argument to a "Map" function, where you choose what to emit to the result set. The result will be a JSON object with a rows array, containing all the emitted objects. Here is the map function from the users view:
This might sound wasteful - so we have to go through all our data, even though we're only interested in a particular well-defined subset? Somehow, however, CouchDB mitigates this, due to the way the data is stored on disc. It also remembers the result of passing a certain document to a certain map function, making the database every bit as fast and resilient as its table-based counterpart.
Another view in the Tristania app is the Statistics view, which also uses the Reduce function to return a single, aggregate object:
The result the same JSON structure as before, but the rows array now has only one value:
Still early days for the app, so as you can see above, it needs a lot more votes for the statistics data to be meaningful.
As with the notes on YQL etc, this isn't meant to be a CouchDB primer, but merely a way to wet your appetite if you still haven't made its acquaintance.
GitHub
So here we are definitely preaching to the choir, but I just wanted to put it to protocol that without Github, we never would have made it. We're situated in different parts of Sweden, and have been working in parallell on different parts of the application. Here's a snapshot of our Github app Network graph, showing our intertwined commits:
In our horrid pre-using-version-control days, we never could have pulled this off. Github for president!
PS
And, we know we've said it before, but it cannot be said too many times - go buy Rubicon, Tristania's new album! Now! :)


