There’s no place like ::1

Titanium With Coffeescript and Backbone.js - Part 2

| Comments

In Part 1 I looked into Titanium with Coffeescript and a Rakefile for compiling and run from the CLI. Now it is time to see how I integrate with Backbone.js for pure REST awesomeness.

Warning: I will assume you are using Ruby on Rails as the server backend.

Integrating backbone.js libraries

Backbone.js is often used with underscore.js, and I actually use the later a lot. So the first thing I do is to install backbone and underscore under Resources/lib directory, and import it on my file.

Now the thing is, Backbone is pure Javascript and by default has no idea on how to make a HTTP call, besides using jQuery for AJAX. So I dug a little on the internet and found a Titanium compatible Backbone.Sync module that you can see on this gist. This version uses Ti.Network.HTTPClient to proper transmit the HTTP requests.

Making Rails accept the HTTP POST data

Now that my Titanium App knows how to make proper HTTP requests, I have another problem. During my tests I couldn’t make Titanium send the model’s attributes in the correct format for Rails to recognize them. Somehow Rails is supposed to accept the body encoded as JSON but I never got it to work. Also, I found no way of sending Files (TiBlob) to Rails without using my custom solution (how do you encode binary data on JSON?).

So I needed to invent a way of formatting the model’s attributes using Rails’ standards. You’ve probably noticed that on line 28 I call model.toParams() if I’m sending a POST body. So I hacked a quick way of generating Rails compatible attributes, and extracted into a class called QueryStringBuilder:

This class uses underscore calls to detect variable types, and should handle most of the basic types on your application. It should handle nested attributes too, and notice that when an attribute is a file (TiBlob) it just passes the object down the stack, because later, the Titanium HTTP module will handle it and encode on the POST body.

Defining a Backbone model

So armed with the previous tool, I could for instance write a Backbone module to handle blog posts like this:

Binding to Titanium Views

So with the previous mechanism, it’s very easy to tie Backbone Models to Titanium Views. Remember the way I did ViewControllers on part 1? Let’s build one that manages blog posts using a TableView:

So a simple fetch and massage the data to fit the tableview. Nothing fancy so far right? Now the best part comes when you’re showing a Post model:

Notice line 16 and 17. We are literally binding the model attributes to a view (in our case, a row). So imagine that for some reason, you change the title of the post (by doing @post.set({title:"foo"})), Backbone would trigger the change, and the table view row would automatically display the new value! For instance, imagine an Edit button that shows a drill down view controller to edit the post. As soon as you change a value on the model, the parent view will be updated! That for me was plain awesome when it worked for the first time.

So by using this method, all I have to do is to bind model attributes to Titanium views, and all changes are automatically propagated to the correct places! Using this setup saved me a lot of time and code writing REST applications with iOS and Titanium.

Now this blog post is getting big and there are some things I didn’t talk, like how to save models on our Rails backend, and how this setup works on Android (hint: it does work!). Maybe I’ll leave that and a few tricks for part 3? :-)