Tuesday, October 20, 2009

Lotto Results for the iPhone

I'm proud to announce my first iPhone application I developped at Front Foot has been released!

Winning Numbers is a mobile website adapted to all phones in australia, but you can enjoy it now as a native application for your iPhone under the name Lotto Results.

It provides for now the latest results and dividends for all of the major australian lottery games: Oz Lotto, Powerball, Lotto, Tattslotto, Gold Lotto, and more... You can also save your winning numbers to quickly find them in the latest results, enjoy!

Monday, October 12, 2009

Updated dam5s-happymapper to use Nokogiri

I've updated my version of Happymapper to use Nokogiri. It should be faster. The original Happymapper had already been forked to use Nokogiri by Roland Swingler.

Nokogiri is a ruby gem to parse XML and HTML using XPath or CSS selectors. It's written mostly in C, and is very fast. I intend to use this version of Happymapper in an upcoming project with intensive parsing!

Thursday, October 8, 2009

Asynchronous Tasks in your iPhone App

One thing that as made web applications much easier to use in the last few years is the integration of Ajax into web pages. Before that, each click of the user would block the application until the next page loads... not really a great user experience.

Now when you want to trigger a long task in the background, you can use Javascript to trigger asynchronous requests... that is just great!

Well in standard applications design, it is also very handy to be able to do such thing, and we usually do it using threads. The iPhone platform obviously provides everything you need to perform that, and that's pretty simple! Just awesome! Here is how it works...

The documentation you want to read is the NSOperation Class it provides the tools to trigger a task in the background. And as the documentation says, you will most of the time want to manage a queue of operations rather than just a single operation. So the best thing to do (in my opinion) is to create a Manager (singleton) which owns a queue of operations: NSOperationQueue Class.

This way you can add operations to the queue, and they will all be treated in order. A good example of this kind of manager is the ConnectionManager of the ObjectiveResource library.

You can use it this way:

- (void)fileDownloaded: (NSData *)data {
    // Do stuff here
}
- (void)downloadFile: (NSUrl *)url {
    // Download file here

    [self performSelectorOnMainThread: @selector(fileDownloaded:)
                           withObject: downloadedData
                        waitUntilDone: YES];
}

And somewhere in your code trigger the asynchronous download:

[[ConnectionManager sharedInstance] runJob: @selector(downloadFile:)
                                  onTarget: self
                              withArgument: url];

That's it! So when you call runJob on the connection manager, it queues the job in the operation queue... so if you need to download ten files, they will be processed asynchronously one-by-one while the user is still using your app, without interruption.

Hope this was helpful!

Tuesday, October 6, 2009

Rails Routes according to the Domain

Routing using Rails is quite simple, you define routes and where they point at. The order in which routes are declared defines their priority. Very simple.

Now Rails also provides conditions on routes according to the HTTP method used, and using the request_routing plugin we can use more conditions. We specially use it for the domain, or sub domain used for example. The Frontfoot website and the Frontfoot mobile site are the same rails application, they just use different routing according to the domain used.

map.connect '/:action',  :controller => 'mobile',
                         :conditions => { :domain => /\.mobi/i }
map.connect '/:action',  :controller => 'main'

That works well if the domain has only one TLD like frontfoot.mobi, but if the domain has two TLDs it doesn't work. In this case we do the test on frontfoot.mobi so it works well.

Now what if we have two domains like for example frontfoot.com.au and ffmobile.com.au. Well that doesn't work. The :domain option will test the domain against 'com.au' we could then use sub-domain to get 'frontfoot' but in that case if we use 'www' it won't work because the :subdomain option tests only the first sub-domain.

So here is the solution! I have written a fork of the plugin to add a :domain_2 option which just gets the domain considering it has 2 TLDs. And there you go you can write:

map.connect '/:action',  :controller => 'mobile',
                         :conditions => { :domain_2 => /ffmobile\.com\.au/i }
map.connect '/:action',  :controller => 'main'

Enjoy! It's tested and on my github. :)