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 main.coffee
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? :-)