Entity view (Content)

SproutCore and PhoneGap

By ebarter
May. 20, 2011

Recently I've been working on bringing a SproutCore application to a native iPad app by way of the PhoneGap platform. While we had our app working in the browser, we faced a number of challenges and caveats going down this path, and picked up a number of useful tips that I'd like to share. First off, Colin Campbell, a core SpoutCore developer, has a blog postwith some very useful information and a Ruby-based build script for packaging your SproutCore app for PhoneGap. I had to make a small modification to this script to get images to work properly. As far as I know we were using sc_static to generate the correct path, but it took adding this to the build script to get everything to work properly:

['stylesheet-packed.css'].each do |file_name|
  path = File.join(app_path, file_name)
  if File.exist?(path)
    data = File.read(path)
    data.gsub! /\/static\//, '../../../../static/'
    File.open(path, 'w+'){|f| f.puts data }

The full script is available here. Secondly, we no longer have the benefits provided by sc-server, namely the proxying of requests. The main purpose of this proxy functionality is to get around the limitations of cross-domain requests. So how did we get around this with PhoneGap? Well, luckily for us, PhoneGap is, at its core, just a UIWebView which doesn't face the same cross-domain restrictions. We still had to rewrite some of our requests, however, to utilize JQuery's AJAX functionality (hat tip to Johannes Fahrenkrug for the tip). Our request code now generally looks like the following:

self = this;
if (SC.buildMode === 'debug') {
    .set('isJSON', YES)
    .notify(this, this._doSomething, { query: query, store: store })
} else {
  $.getJSON(OurApp.server + request + '&callback=?', null,
    function(data, textStatus, xhr) {
      SC.run(function() {
        var response = SC.Response.create({ request: null, body: data, status: textStatus });
        self._doSomething(response, { query: query, store: store });

When we're using sc-server, the buildMode is 'debug', otherwise the above script builds for 'production'. Finally, a tip! It seems impossible, in my experience, to create a cookie from inside our app, so we had to improvise. Since we are targeting a small subset of browsers (namely Safari for iOS) we decided to just use HTML5 local storage instead. Hey presto, we can store what we need for our app!

Post Tags: