As I mentioned previously, I’ve been having a lot of fun lately writing micro web applications using the Sinatra framework. I’ve found myself thinking of a simple idea for an application, developing it fairly quickly using Sinatra and some technologies or techniques that are new to me and then getting it out there running for free on Heroku. I’ve developed two other applications this way since blogging about my bespoke URL shortener jtblog.me: UUID Waster and Truth Tables.
UUID Waster
I think I first came across the idea of the 128-bit Universally Unique Identifier (UUID) shortly after Windows 95 came out. As the World Wide Web was still in its infancy you had to learn about hacking Windows from magazines printed on actual paper and sold in a physical shop. A bizarre idea, I know.
Reading one of those magazines I learned that you could use the Registry Editor—at your own risk, they were at great pains to point out—to tweak Windows in all sorts of interesting and officially undocumented ways. For example, you could rename the Recycle Bin to anything of your choosing, an option that wasn’t exposed by the Windows shell at the time.
I noticed that the Windows registry was crammed full of strange long hexadecimal strings, which I eventually learned were what Microsoft calls Globally Unique Identifiers or GUIDs. Even later I learned that these were being used as COM class IDs and that they were generated programmatically without any fear of being the same as an existing identifier. Still a bit fascinated by this idea all these years later, I thought it would be amusing to create a web application that frivolously wasted UUIDs at the rate of one a second. Thus, UUID Waster was born. It’s not an original idea, but I went ahead with it anyway.
As a side effect of creating UUID Waster I also took the opportunity to use jQuery’s AJAX support, which was a first for me because previously I’ve used Prototype. I also used a different database and ORM tool from the MySQL/ActiveRecord combination used in my Rails applications. UUID Waster uses a SQLite 3 database when running locally in development and in production it uses PostgreSQL, which is part of the standard Heroku stack. I chose Data Mapper as the ORM layer. So that’s a pointless application that as a side effect gave me exposure to three new things.
Truth Tables
I can never remember the Boolean logic truth tables for the slightly more exotic operations such as XOR (Exclusive Or) and it always seems to take me longer than I’d like to look them up. With this in mind I decided to create a simple application that would act as a reference. Then I bought the Meet jQTouch PeepCode screencast, got very excited by what I saw and realised that I could also effectively turn it into an iPhone app.
I created the web version first and used it as an opportunity to dip my toe into the world of HTML5 and CSS3 (the rounded corners are done using CSS3). I also used Haml and Sass on the server to generate the markup and stylesheet respectively.
Next, I moved on to creating the iPhone-specific version using the jQTouch framework. To be honest, this was pretty hard work because although it was easy to get the basic bones of the application up and running in no time using jQTouch, I wanted an installation screen and I wanted things to still work without an Internet connection, because after all this is simply an app that’s displaying read-only reference information.
The desire for an installation screen was simply because asking the user to add the application to their home screen makes it essentially indistinguishable from a native iPhone application written in Objective C. You can provide a custom application icon, a startup screen and you don’t have to worry about Mobile Safari displaying its toolbar at the top.
Both of these noble objectives were surprisingly difficult to achieve. An installation screen is quite hard to do because jQTouch wants to take over everything it comes into contact with and I didn’t want my installation screen within its grasp, as I wanted to style it myself. I chose to have the elements comprising the installation screen and the application proper dynamically shown or hidden within a single HTML file so that a single URL could be used. The reason for this is that otherwise the app gets the URL of the installation screen when it’s added to the home screen, which causes further complications down the line.
Eventually I hit upon the trick of using JavaScript to dynamically change the ID attribute of the main container div element which enables jQTouch to control the application when it’s running standalone but to leave it alone otherwise. This works well.
if (window.navigator.standalone) { $("#installation").hide(); var $container = $("#container"); $container.attr("id", "jqt"); $container.show(); // Initialize jQTouch (not shown)... } else { $("#installation").show(); }
HTML5 offline application caching is how you make one of these web-apps-masquerading-as-a-native-app work without an Internet connection. It sounds simple in theory: you create a cache manifest file that lists the other assets needed for things to work offline. On the iPhone what actually happens is that the assets are downloaded in the background and stored in a BLOB column within a SQLite 3 database on the phone.
So much for the theory. The reality is that the slightest error in the cache manifest file will cause the whole thing to stop working and you probably won’t have a clue why because it’s extremely hard to debug. During development I was testing Truth Tables on my Mac by using the iPhone simulator which comes with the iPhone SDK. At one point I was following the instructions in the excellent Building iPhone Apps with HTML, CSS, and JavaScript book to inspect the simulator’s application cache database by using the sqlite3 command-line interface. It was a nice idea but there weren’t any rows for my application in there at all! Needless to say, I got it working eventually but more by trial and error than by judgement. I think the final result is worth it.
- The source code for both UUID Waster and Truth Tables is available on GitHub.
Comments
There aren’t any comments on this post. Comments are closed.