Ionic & AngularJS  on Cordova

Software Developer & COO

Sophilabs co-founder

#nodejs  #python  #django  #phonegap  #c#

One of the most used tools for multi-platform mobile development

Apache Cordova

Create multi-platform hybrid mobile apps

     WebView + HTML + CSS + JS + Native Plugins

Developed by Nitobi in 2009, acquired by Adobe in 2011 and forked to Adobe Phonegap

Works on: iOS, Android, Windows Phone, Blackberry, Symbian, Ubuntu Touch, Firefox OS and many others

How to use it


$ sudo npm install -g cordova

$ cordova create hello com.example.hello HelloWorld

$ cordova platform add android

Install it using Node's Package Manager

Create the project structure

Add platforms

Test & Debug


#! /usr/bin/env python
 
import SocketServer
import SimpleHTTPServer
import urllib2
from urlparse import urlparse, urljoin
 
PORT = 8000
FOLLOW_REDIRECT = True
PROXY_RULES = {
    '/halo/' : 'http://www.oxfordeconomics.com/'
}
 
class Proxy(SimpleHTTPServer.SimpleHTTPRequestHandler):
    def __do_proxy(self):
        prefix = None
        for key in PROXY_RULES.iterkeys():
            if self.path.startswith(key):
                prefix = key
                break
 
        if prefix:
            # Strip off the prefix.
            url = urljoin(PROXY_RULES[prefix], self.path.partition(prefix)[2])
            hostname = urlparse(PROXY_RULES[prefix]).netloc
 
            body = None
            if self.headers.getheader('content-length') is not None:
                content_len = int(self.headers.getheader('content-length'))
                body = self.rfile.read(content_len)
 
            # set new headers
            new_headers = {}
            for item in self.headers.items():
                new_headers[item[0]] = item[1]
            new_headers['host'] = hostname
            try:
                del new_headers['accept-encoding']
            except KeyError:
                pass
 
            print 'PROXY to ' + url
            prox_req = self.__do_request(url, body, new_headers)

            if (prox_req.code != 200):
                self.send_error(prox_req.code, prox_req.msg)
            try:
                self.copyfile(prox_req, self.wfile)
            except IOError, e:
                print "ERROR: ", e
        else:
            SimpleHTTPServer.SimpleHTTPRequestHandler.do_GET(self)
 
    def __do_request(self, url, body, headers):
        req = urllib2.Request(url, body, headers)
        try:
            response = urllib2.urlopen(req)
        except urllib2.URLError, e:
            if FOLLOW_REDIRECT and hasattr(e, 'code') and (e.code == 301 or e.code == 302):
                headers['host'] = urlparse(e.url).netloc
                return self.__do_request(e.url, body, headers)
            else:
                response = e
        return response
 
    def do_GET(self):
        self.__do_proxy()
 
    def do_POST(self):
        self.__do_proxy()
 
SocketServer.ThreadingTCPServer.allow_reuse_address = True
httpd = SocketServer.ThreadingTCPServer(('', PORT), Proxy)
print "Starting proxy server at ", PORT

$ adb logcat | grep Cordova

Proxy Server for local development

Debug android app using adb

Plugins


$ cordova plugin add org.apache.cordova.battery-status

$ npm install -g plugman
$ plugman -d --platform android --plugin org.apache.cordova.battery-status

Install the battery status plugin

Using plugman

Create you own Plugin

package org.apache.cordova.plugin;

import org.apache.cordova.api.CordovaPlugin;
import org.apache.cordova.api.PluginResult;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

/**
 * This class echoes a string called from JavaScript.
 */
public class Echo extends CordovaPlugin {
    @Override
    public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
        if (action.equals("echo")) {
            String message = args.getString(0); 
            this.echo(message);
            return true;
        }
        return false;
    }

    private void echo(String message, CallbackContext callbackContext) {
        if (message != null && message.length() > 0) { 
            callbackContext.success(message);
        } else {
            callbackContext.error("Expected one non-empty string argument.");
        }
    }
}

exec(<successFunction>, <failFunction>, <service>, <action>, [<args>]);

Build & Test


$ cordova build android

Build apk for Android


$ cordova emulate android

Run the Android emulator


$ cordova run android

Run it on plugged devices

BUT, how do I build apps for Microsoft and Apple phones in my Linux env?

Phonegap Build to the rescue!

Ship it using Phonegap build


$ sudo npm install -g phonegap

Install phonegap system wide


$ phonegap local build android

Build for android locally


$ phonegap remote login -u iamreallyadog@gmail.com -p mYpASSw0RD
$ phonegap remote build ios

Build for iOS remotely

MVC framework to create Single Page Web Applications

Two way data-binding

Routing & Views

Templates & directives

Built with testing in mind

Services & Dependency Injection

...learn something by doing

Templates expressions in Action

git checkout -f step-0

Controllers, Models & Testing

git checkout -f step-2

Two-way data binding

git checkout -f step-4

XHR & Dependency Injection

git checkout -f step-5

Routing & Multiple views

git checkout -f step-7

http://localhost:8000/app/

Angular Services

Angular Directives

Styles (SASS)

Command line tools

What is it?

"Open source front-end framework for

developing hybrid mobile apps with HTML5"

Command line tools


$ npm install -g cordova ionic

Install it using npm


$ ionic start myApp tabs

Create a new app including cordova structure + ionic dependencies


$ ionic platform add ios
$ ionic build ios
$ ionic emulate ios

Run it... 

CSS Components


$ pip install scss

Install SASS


$ scss --watch scss/app.scss:css/style.css 

Run the watcher

Angular Directives & Services

$ionicActionSheet

Starter projects

DEMO TIME!

What is coming...

Questions?