I’m currently developing an iPhone app with Appcelerator’s Titanium that communicates with a Rails backend. Doing so I found a few problems and here is how I solved them. This is the first time I work with Titanium, so don’t expect something fancy ; )

Ajax GET request with params:

We’ll use Titanium.Network.HTTPClient, if you have never used it I suggest that you take a look a this awesome example in the Titanium wiki that perfectly covers the basics.

Say our rails app is a blog at the domain: http://www.railsblog.com, and we want to get the all posts that are written in Spanish by the author ariera. My first attempt to do so looked like this:

    var postsReq = Titanium.Network.createHTTPClient();
    postsReq.open("GET", "http://www.railsblog.com/posts");
    var params = {
    	language: "spanish",
    	author: "ariera"
    };
    postsReq.send(params);

It took me some time to understand why, but that code doesn’t work as you would expect it to work. Although we clearly specified that we wanted to do a GET request it will do it as a POST. The reason why this happens is that when you pass any parameter to the send method it automatically converts the request into POST.

My solution was to manually construct the url with parameters using encondeURI:

    var url = "http://www.railsblog.com/posts";
    var params = "?language=spanish&author=ariera";
    var encodedURI = encodeURI(url + params);
    
    var postsReq = Titanium.Network.createHTTPClient();
    postsReq.open("GET", encodedURI);
    postsReq.send();

And that finally worked. But was that all? Of course not ;-P

Titanium enable your Rails app:

When testing the iPhone app with my local copy of this railsblog I got the most weird succinct not-descriptive error Rails ever gave me:

Started GET "/posts?language=spanish&author=ariera" for 127.0.0.1
  Processing by PostController#index as 
Completed 500 Internal Server Error in 1ms

NoMethodError (undefined method `ref' for nil:NilClass):
  

Rendered .../gems/actionpack-3.1.0.rc4/lib/action_dispatch/middleware/templates/
    rescues/_trace.erb (1.1ms)
Rendered .../gems/actionpack-3.1.0.rc4/lib/action_dispatch/middleware/templates/
    rescues/_request_and_response.erb (0.9ms)
Rendered .../gems/actionpack-3.1.0.rc4/lib/action_dispatch/middleware/templates/
    rescues/diagnostics.erb within rescues/layout (4.8ms)

that NoMethodError (undefined method 'ref' for nil:NilClass) error drove me crazy for a while. Apparently this is due to a mix of user agent and Mime Types handled incorrectly by Rails. Following this stackoverflow answer I did this:

    # config/initializers/mime_types.rb
    Mime::Type.register_alias "text/html", :titanium
    # app/controllers/application_controller.rb
    before_filter :handle_titanium
    
    def titanium_user_agent?
      @mobile_user_agent ||= ( request.env["HTTP_USER_AGENT"] && 
        request.env["HTTP_USER_AGENT"][/Titanium/] )
    end
    
    def handle_titanium
      request.format = :titanium if titanium_user_agent?
    end