I’ve recently been given the task of re-writing a series of iPhone apps to be multi-platform. I’d like to share some preliminary notes on the procedures and conventions I’ve settled on for this project.

Technologies in Use

If you’re already familiar with these technologies, you can skip to the specifics of how they’re structured.

Each new app is built on the same technologies: a single-page web app built using the Ember.js framework, which runs on the phones via a technology called Phonegap/Cordova (originally known as Phonegap, now named Cordova).

Ember is a javascript framework for creating single page web apps. By itself Ember does not have a comprehensive set of conventions and tooling for interacting with Ember projects. This is in comparison with things like Django or Ruby on Rails which have tools and conventions to manage code.

Because of this, the Ember part of each app is created and managed using the command-line tool Ember CLI, a project created by the Ember community. Ember CLI enforces a strict set of conventions on how an Ember app is developed, as well as a set of tools to make working on that Ember app easier. Because it has it’s own rules, even if one is familiar with Ember, you must also be familiar with Ember CLI.

Cordova lets you write cross-platform smartphone apps. It does this by requiring you to write your app as a single-page web-app, which Cordova runs inside a webview on each different device. Additionally, Cordova allows the web-app to access various smartphone features (e.g. geolocation, notifications, etc) by extending the standard Javascript API available in the web view. This means that though each app is a web-app, it uses some non-standard api’s only provided by Cordova to access certain features.

Folder Layout

Each application is composed of a Cordova app as the root directory of that app, and the Ember-CLI app as a folder within the root. The Ember-CLI app will have the same name as the app, but with ember- prepended. To create an example app with the same structure as the official new apps, enter the following:

$ cordova create example
$ cd example
$ ember new example-ember # The name of the executable for Ember-CLI is just `ember`

This will create a directory structure that looks like this:

example/
├── config.xml
├── ember-example
│   ├── Brocfile.js
│   ├── README.md
│   ├── app
│   ├── bower.json
│   ├── bower_components
│   ├── config
│   ├── node_modules
│   ├── package.json
│   ├── public
│   ├── testem.json
│   ├── tests
│   └── vendor
├── hooks
├── platforms
├── plugins
└── www
    ├── css
    ├── img
    ├── index.html
    └── js

This is the basic structure of each app - an Ember-CLI application inside of a Cordova application.

Additional Modifications

In addition to this particular folder structure, some settings are modified. Some of these changes where originally sourced from this post by Mitchell Johnson of Atomic Object, but these changes are also outlined here.

Changing the Build Directory

First, the build directory of the Ember-CLI app is changed from the dist folder in the Ember-CLI app (example/ember-example/dist/) to the www folder in the root folder of the application (example/www/). This is done by modifying the .ember-cli file in the Ember-CLI app, adding a setting for output-path:

{
    "output-path": "../www"
}

Now, when the Ember-CLI app is built using the command ember build, the compiled output will be put into the www folder so that Cordova can package that into an app.

Adding Cordova Build Hooks

The second modification is to add build hooks to Cordova, so when the Cordova app is built, it also re-builds the Ember-CLI app. According to the post on Atomic Object, this is best done by adding a file in the before_prepare folder of the hooks folder in the Cordova app. The name of the file is hooks/before_prepare/build_ember_app.sh and its contents are:

#!/bin/bash
# This script is different than the one in the post by Atomic Object. It's
# different to account for our different directory structure.
if [[ $CORDOVA_CMDLINE =~ release ]]; then
    echo "Creating production build of ember app"
    (cd ember* && ember build --environment=production)
else
    echo "Creating debug build of ember app"
    (cd ember* && ember build)
fi

Make this script executable with the command chmod +x hooks/before_prepare/build_ember_app.sh.

Changing the BaseURL and LocationType of the Ember-CLI app

By default, an Ember-CLI app is set up with a locationType of auto. The setting of auto is done to make the urls created by the ember app as clean looking as possible. However, it breaks the app when it’s accessed as a file on the local file-system. To make an Ember-CLI app behave when served from arbitrary locations, we must change a variable in the config/environment.js file. Inside that file, change the variable locationType near the top of the folder to have the variable hash instead of auto.

Rationale

Each app is structured this way to make building as easy as possible. To build both the Cordova and the Ember-CLI app, run the cordova build command in the root of the application development tree. Because of the build hook added above, Cordova will build a fresh Ember-CLI app before packaging it all up as an app for the appropriate platforms.