May 17, 2013

More work on Checkvist mobile infrastructure

This is the next post regarding Checkvist mobile project.

Javascript

Trying to figure out some framework requirements. What I need is:

  1. Single JS file from multiple JS files (modules)
  2. Offline app loading
  3. Client-side undoable persistent deferrable commands

For the first point I'm going to use RequireJS (and its optimizer r.js). Also, it looks like later it is cool to use almond to optimize load times.

After some jumps, managed to make requireJS to work with CanJS MVC and Zepto jQuery replacement (and even r.js optimizer works!).

For offline apps loading, offline HTML manifest works just fine. There is a trick, though - to be able to load a non-mentioned resource in the manifest file (in development mode), one have to add

NETWORK:
*

in addition to usual resources section.

Another note: if there is any problem while loading resources from the manifest file, all other files of the app are not re-loaded.
This is quite critical - you have to make sure that all resource files are present.

The third point of the list I defer so far, until real interaction with the server is implemented.

CSS

It is cool to have a single JS file, but I'd like to have the similar for the CSS.

For this, Sass looks rather good, given that it optimizes @imports + gives tons of syntax sugar for CSS.

Adding Sass wasn't difficult:

  1. Make sure ruby is installed
  2. Create Gemfile with

    source 'https://rubygems.org'
    gem "sass"
    gem 'rb-fsevent', '~> 0.9.1'
    gem 'rake'
    
  3. gem install bundler && bundle install
  4. Create Rakefile:

    require 'sass/plugin'
    namespace :sass do
      task :env do
        Sass::Plugin.options[:template_location] = 'www/scss'
        Sass::Plugin.options[:css_location] = 'www/css'
      end
    
      desc 'Updates stylesheets if necessary from their Sass templates.'
      task :update_and_compress => :env do
        `rm www/css/*`
        Sass::Plugin.options[:style] = :compressed
        Sass::Plugin.update_stylesheets
      end
    
      desc 'Watch stylesheets'
      task :watch => :env do
        Sass::Plugin.watch
      end
    end
    
    namespace :requireJs do
      desc 'Run optimizer/uglifier for JS code'
      task :optimize do
        `node r.js -o app.build.js`
      end
    end
    
    namespace :cl do
      task :build => ["sass:update_and_compress", "requireJs:optimize"] do
        print "Done!
      end
    end

For automatic conversion of scss files to css peers during the development, I have to keep the following command running:

rake sass:watch

By the way, Sass mixins are rather useful, given that there are tons existing examples, for instance this Retina support mixin.

HTML offline issues

After having continuous trouble with updating HTML5 offline manifest file and double page refresh after each change I decided to go a way when the manifest is added to the page only while building the production version of the site. I've added a very simple task to Rakefile:

task :update_for_offline do
    index = "build/www/index.html"
    updated = IO.read(index).sub("<html>", "<html manifest='checkvist.manifest'>")
    IO.write(index, updated)
end

So far so good. MVC is almost in place, JS and CSS are united and minified in the project. Time for the real meat.

May 9, 2013

Day one, persistent storage and native HTML5 wrapper research

I'm going to keep a log of useful notes on a way to mobile Checkvist app. Not sure how patient I will be, let's see.

Persistent storage

First, I tried to figure out the current options for offline storage in the mobile app.

Looks like the most obvious choice could be WebSQL, but this spec is deprecated since 2011, though supported on all major mobile platforms.

The alternative standard, IndexedDB, is much less wide-spread, and less performant.

Here is a useful overview of offline options, and here are slides from a related talk (with a big list of intermediate libraries for offline storage).

So far, I'm considering using this Ydn-DB library to create an intermediate layer for data persisting.

Native wrapper for HTML5 app

Tried PhoneGap, which is essentially Apache Cordova

This library allows to create a native app, which wraps a Web-browser and which provides a bunch of APIs for accessing native features of the device.

The first thing which stroke me was that I had to use symbolic links to share common part of the app between iOS and Android versions of the same application.

The code of the application is deployed with the native app, but you can make AJAX calls to remote servers (though I didn't test it yet).

By the way, Android plugin for IntelliJ IDEA works with Android Cordova app just fine :)

Checkvist mobile app, take 2

In short, the idea is to create a new mobile app for Checkvist with the following key capabilities:
  • offline read/write operations
  • undo for commands
  • Android/iOS compatibility
  • rich touch interface
  • using device camera to post photos as attachments in Checkvist
  • work with external keyboards
  • app upgrade without need for app approval in iOS store
I'd like to achieve this using pure HTML5/JS/CSS + native app wrapper (mostly for marketing via Apple store/Google Play categories). But anyway, it should be possible to reach the app using http://m.checkvist.com.
The task is big and ambitious, but it looks a great way to learn something new :)