Building Mobile Applications

with

HTML/Js/Css

and

Cordova

Program

Matteo Magni

Twitter @ilbonzo

Github @ilbonzo

Yeah!

Advantages

mmm?

Disadvantages

Alternative

PhoneGap was originally developed by Nitobi, a company acquired by Adobe in 2011. After it was acquired, Nitobi donated the PhoneGap code base to the Apache Software Foundation (ASF) under the project name Cordova.
Cordova is the name of the street in Vancouver where Nitobi's offices were located and where the company create the first version of framework

Cordova vs Phonegap

PhoneGap, Cordova, and what’s in a name?
"PhoneGap is a distribution of Apache Cordova. You can think of Apache Cordova as the engine that powers PhoneGap, similar to how WebKit is the engine that powers Chrome or Safari.
(Browser geeks, please allow me the affordance of this analogy and I’ll buy you a beer later.)"

Cordova

https://cordova.apache.org/

Phonegap

http://phonegap.com/
Cordova/PhoneGap is a free and open source framework that allows you to create mobile apps with
html, css and javascript.
Think of PhoneGap as a web view container that is
100% width and 100% height

Phonegap workflow

support platform

platform details for simulator

Ripple

Emulate app in desktop browser with Chrome extension Ripple

Html5

Viewport

The viewport meta tag The viewport meta tag was introduced by Apple with iOS 1.0 and is largely supported in all the major mobile browsers. When a web page doesn't fit the size of the browser, the default behavior of a mobile browser is to scale it. The viewport meta tag is what you need in order to have control over this behavior.

Javascript

jQuery

"jQuery: The Write Less, Do More, JavaScript Library"

"jQuery is defintely the way"

"YOU MIGHT NOT NEED JQUERY"

http://youmightnotneedjquery.com/

Performance

I use jQuery and I love it, but I will not advise the use of jQuery when building a hybrid multi-page app. Also, if the jQuery library is downloaded once, the file is parsed each time it's included in an HTML page. Performance on mobiles is crucial. If you don't seriously consider optimizing each aspect of your app, you risk losing users. Bad performance can also lead to high battery consumption.

Single Page Web App

Optimization

WTF???

Frontend developer

code organization

backbonejs.org

" JavaScript library with a RESTful JSON interface and is based on the model–view–presenter (MVP) application design paradigm"

angularjs.org
"AngularJS lets you extend HTML vocabulary for your application. The resulting environment is extraordinarily expressive, readable, and quick to develop."

emberjs.com
"A framework for creating ambitious web applications."

React
"A javascript library for building user interfaces"

Meteor
"The fastest way to build javascript apps"

tool and library dependency

package.json

{
  "name": "booker",
  "dependencies": {},
  "devDependencies": {
    "grunt": "~0.4.1"
  },
  "engines": {
    "node": ">=0.8.0"
  }
}
$ npm install
$ npm update

bower.json

Bower
{
  "name": "booker",
  "dependencies": {
    "jquery": "~1.9.0",
    "underscore": "~1.4.3",
    "backbone": "~1.0.0"
  },
  "devDependencies": {}
}

.bowerrc

{
    "directory": "app/bower_components"
}

repetitive tasks

Grunt

npm install -g grunt

Gruntfile.js

module.exports = function (grunt) {
  // show elapsed time at the end
  require('time-grunt')(grunt);
  // load all grunt tasks
  require('load-grunt-tasks')(grunt);
  ...
}
npm install -g grunt-cli
# grunt in only project
npm install grunt

Grunt plugin

npm install -g gulp-cli

gulpfile.js

var gulp = require('gulp');
gulp.task('default', function() {
  // place code for your default task here
});

Yeoman

yeoman.ioTHE WEB'S SCAFFOLDING TOOL FOR MODERN WEBAPPS
This will install Grunt, Gulp, Webpack, Bower... automatically.
$ npm install -g yo

Altre utility

strict mode

strict mode
Converting mistakes into errors

Non-strict mode

Strict mode

function someSetup() {
  a = Math.PI;
}
someSetup();
console.log(a);
// 3.14159...
"use strict";
function someSetup() {
  a = Math.PI; // BOOM!
}
someSetup();
console.log(a);

throws ReferenceError

"Strict mode forbids implicit creation of global property 'a'"

Non-strict mode

YOLO mode

Strict mode

function someSetup() {
  a = Math.PI;
}
someSetup();
console.log(a);
// 3.14159...
"use strict";
function someSetup() {
  var a = Math.PI;
}
someSetup();
console.log(a); // BOOM!

throws ReferenceError

"Can't find variable: a"

Development Cordova/PhoneGap app

Phonegap Architecture

cli

Cordova Cli

https://github.com/apache/cordova-cli
$ npm install -g cordova

Cordova Cli

$ cordova create evvent-cordova com.ilbonzo.evvent "Evvent"
$ cd evvent-cordova

Cordova Cli tree

Phonegap Cli

https://github.com/phonegap/phonegap-cli
$ npm install -g phonegap

Phonegap Cli

$ phonegap create evvent-phonegap com.ilbonzo.evvent "Evvent"
$ cd evvent-phonegap

Phonegap Cli tree

Simulators

https://cordova.apache.org/docs/en/latest/guide/platforms/ios/

iOS

iOS

Cordova

$ cordova platform add ios

iOS

run ios project

Once created, you can open it from within Xcode. Double-click to open the evvent-cordova/platforms/ios/Evvent.xcodeproj file.

emulate

cordova requirements

$ cordova requirements
Requirements check results for ios:
Apple OS X: installed darwin
Xcode: installed 7.3.1
ios-deploy: installed 1.8.6

ios-deploy

ios-deploy

Install and debug iPhone apps from the command line, without using Xcode
https://github.com/phonegap/ios-deploy

ios-sim

ios-sim

Command-line application launcher for the iOS Simulator
https://github.com/phonegap/ios-sim

serve

Android

Android

https://cordova.apache.org/docs/en/latest/guide/platforms/android/
#~/.bashrc
export PATH=${PATH}:~/adt-bundle/sdk/platform-tools:~/adt-bundle/sdk/tools
$ brew install ant

Android

Cordova

$ cordova platform add android

Create eclipse new project from existing source

Android virtual device manager

$ cordova run android

Phonegap Cli

command

iOS

Phonegap

$ phonegap build ios

serve

Phonegap

$ phonegap build android

Phonegap

$ phonegap run android

cordova cli multiple version

$ mkdir cordova3.1
$ cd cordova3.1
$ npm view cordova
$ npm install cordova@3.1.0-0.2.0
$ alias cordova31=
  '/path/to/cordova3.1/node_modules/cordova/bin/cordova'
$ cordova31 -v
  3.1.0-0.2.0
  

phonegap cli multiple version

$ mkdir phonegap3.1
$ cd phonegap3.1
$ npm view phonegap
$ npm install phonegap@3.1.0-0.15.0
$ alias phonegap31=
  '/path/to/phonegap3.1/node_modules/phonegap/bin/phonegap'
$ phonegap31 -v
  3.1.0-0.15.0
  

Cordova Compile

android

$ cordova compile --debug
$ ls platforms/android/bin/EvventCordova-debug-unsigned.apk
$ cordova compile --release
$ ls platforms/android/bin/EvventCordova-release-unsigned.apk

Phonegap build

android

$ phonegap local build android
$ phonegap remote build android

Debug sucks

Google Chrome

Simulator

On device

Ripple

http://emulate.phonegap.com/

Emulate app in desktop browser with Chrome extension Ripple

PhoneGap Emulator

The PhoneGap Emulator allows you to test your PhoneGap application from your desktop browser. PhoneGap's JavaScript APIs are avaialble using Ripple, so you can subscribe to deviceready and even stub responses for your custom plugins.

The PhoneGap Emulator requires two free, third-party tools.

The PhoneGap emulator can be invoked with a web request.

The request options are provided as query string parameters and the response will check for all dependencies before opening the Ripple emulator.

// Request
http://emulate.phonegap.com?url=[url]&platform=[platform]

Events Api

Events Api

Deviceready

var app = {
    // Application Constructor
    initialize: function() {
        this.bindEvents();
    },
    // Bind any events that are required on startup.
    // Common events are:
    // 'load', 'deviceready', 'offline', and 'online'.
    bindEvents: function() {
        document.addEventListener(
          'deviceready',
          this.onDeviceReady,
          false
        );
    },
    ...
};
var app = {
    ...
    // deviceready Event Handler
    //
    // The scope of 'this' is the event.
    In order to call the 'receivedEvent'
    // function, we must explicity call 'app.receivedEvent(...);'
    onDeviceReady: function() {
        app.receivedEvent('deviceready');
    },
    // Update DOM on a Received Event
    receivedEvent: function(id) {
        ...
        console.log('Received Event: ' + id);
    }
};

Add deviceready to evvent

Plugins

Device Motion

Accelerometercordova-plugin-device-motion
This plugin provides access to the device's accelerometer. The accelerometer is a motion sensor that detects the change (delta) in movement relative to the current device orientation, in three dimensions along the x, y, and z axis.
$ cordova plugin add org.apache.cordova.device-motion

supported platform

function onSuccess(acceleration) {
    alert('Acceleration X: ' + acceleration.x + '\n' +
          'Acceleration Y: ' + acceleration.y + '\n' +
          'Acceleration Z: ' + acceleration.z + '\n' +
          'Timestamp: '      + acceleration.timestamp + '\n');
};

function onError() {
    alert('onError!');
};

navigator.accelerometer.getCurrentAcceleration(onSuccess, onError);

iOS Quirks

$ cordova create accelerometer-phonegap
  com.ilbonzo.accelerometer-phonegap "Accelerometer Phonegap"
$ cd accelerometer
$ cordova platform add ios
$ cordova plugin add org.apache.cordova.device-motion
$ cordova plugin add org.apache.cordova.console

https://github.com/ilbonzo/Evvent/tree/master/example/accelerometer-phonegap
$ tail -f platforms/ios/cordova/console.log
plugin for console.log to work in the xcode console.
cordova plugin add
  https://git-wip-us.apache.org/repos/asf/cordova-plugin-console.git
  

plugin list

$ cordova plugin ls
[ 'org.apache.cordova.console',
  'org.apache.cordova.device-motion' ]
  
  

Compass

$ phonegap local plugin add org.apache.cordova.device-orientation

function onSuccess(heading) {
    alert('heading: ' + heading.magneticHeading);
};

function onError() {
    alert('onError!');
};

navigator.compass.getCurrentHeading(onSuccess, onError);

iOS Quirks

Only one watchHeading can be in effect at one time in iOS. If a watchHeading uses a filter, calling getCurrentHeading or watchHeading uses the existing filter value to specify heading changes. Watching heading changes with a filter is more efficient than with time intervals.

Geolocation

This plugin provides information about the device's location, such as latitude and longitude. Common sources of location information include Global Positioning System (GPS) and location inferred from network signals such as IP address, RFID, WiFi and Bluetooth MAC addresses, and GSM/CDMA cell IDs. There is no guarantee that the API returns the device's actual location.

This API is based on the W3C Geolocation API Specification, and only executes on devices that don't already provide an implementation.

Maps demo

$ phonegap local plugin add
  https://git-wip-us.apache.org/repos/
  asf/cordova-plugin-device-motion.git
$ phonegap local plugin add
  https://git-wip-us.apache.org/repos/
  asf/cordova-plugin-device-orientation.git
$ phonegap local plugin add
  https://git-wip-us.apache.org/repos/
  asf/cordova-plugin-geolocation.git
  
navigator.geolocation.getCurrentPosition(
  app.onSuccessGeolocation,
  app.onErrorGeolocation
);
var latitude = position.coords.latitude;
var longitude = position.coords.longitude;
var latLng = new google.maps.LatLng(latitude, longitude);
var mapOptions = {
    center: latLng,
    zoom: 16,
    mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById('map'), mapOptions);

https://github.com/ilbonzo/Evvent/tree/master/example/maps

An overview of storage options for Cordova/Phonegap.

LocalStorage

Also known as web storage, simple storage, or by its alternate session storage interface, this API provides synchronous key/value pair storage, and is available in underlying WebView implementations. Refer to the W3C spec for details.

Windows Phone 7 Quirk: Dot notation is not available, so be sure to use setItem or getItem rather than access keys directly from the storage object, as in window.localStorage.someKey.

WebSQL

This API is available in the underlying WebView. The Web SQL Database Specification offers more full-featured database tables accessed via SQL queries.

The following platforms support WebSQL:

IndexedDB

This API is available in the underlying WebView. Indexed DB offers more features than LocalStorage but fewer than WebSQL.

The following platforms support IndexedDB:

db = window.openDatabase('evvent', '1.0', 'Evvent', 5242880);
db.transaction(runTransaction, onError, onSuccess);
function runTransaction(t){
    // t.executeSql('DROP TABLE events');
    t.executeSql('CREATE TABLE IF NOT EXISTS events (name unique)');
}

Add maps to evvent

Add geolocation and maps to Evvent

https://www.songkick.com/developer/location-searchhttps://www.songkick.com/developer/upcoming-events-for-metro-area

Build Phonegap

Simply upload your HTML5, CSS, and JavaScript assets to the Adobe® PhoneGap™ Build cloud service and we do the work of compiling for you.

Matteo Magni

Twitter @ilbonzo

Github @ilbonzo