Introduzione

Apache Cordova è un framework open source per la realizzazione di applicazioni cross-platform usando HTML5. L'approccio usato da Cordova è però unico nel suo genere, perché fonde le capacità native di un dispositivo con la possibilità di realizzare applicazioni usando gli standard web, dando così vita alle applicazioni chiamate ibride.

Il punto di debolezza delle applicazioni web su dispositivi mobili è sempre stato la mancanza della possibilità di usare funzionalità fornite dal produttore per interfacciarsi con i vari componenti hardware, e mentre si spera che in un futuro questa limitatezza possa essere superata attraverso sforzi di standardizzazione, Cordova fornisce una serie di API alle applicazioni che vengono eseguite all'interno del suo container per poter accedere a tali funzionalità, ad esempio sarà possibile utilizzare la fotocamera, l'accelerometro ed il gps.

Cordova si occupa anche di realizzare il pacchetto applicativo (ad esempio file .apk per Android ed .ipa per iOS) per ogni piattaforma supportata a partire dai file della web application.

[caption id="attachment_1992" align="aligncenter" width="953"]Packaging Cordova Packaging Cordova[/caption]

L'applicazione nativa consisterà in una webview (un browser integrato) che mostrerà il contenuto utilizzando tutto lo schermo disponibile. Questo browser embedded potrà utilizzare l'interprete di Javascript fornito dal sistema operativo che ospita l'applicazione ed in più le API esposte da Cordova.

Attualmente Cordova supporta le seguenti piattaforme :

[caption id="attachment_1993" align="aligncenter" width="833"]Piattaforme Cordova Piattaforme Cordova[/caption]

Architettura

A partire dalla versione 3.0 (al momento della scrittura siamo alla versione 3.5.0-0.24) le API sono state separate in diversi plugin, per poter includere nel progetto solamente quelli necessari, e per avere un'architettura più facilmente estensibile anche con plugin di terze parti.

[caption id="attachment_1994" align="aligncenter" width="633"]Architettura Cordova Architettura Cordova[/caption]

Dalla figura (tratta dal libro Apache Cordova 3 Programming) si può notare come ogni singolo plugin sia composto da una parte in Javascript e una parte invece scritta nel linguaggio supportato dalla specifica piattaforma.

Attualmente Cordova fornisce questi plugin:

  • Battery Status
  • Camera
  • Console
  • Contacts
  • Device
  • Device Motion
  • Device Orientation
  • Dialogs
  • File
  • File Transfer

Command Line Interface

Cordova fornisce un tool, chiamato Command Line Interface (CLI) per aiutare lo sviluppatore nella creazione, gestione e deploy di un progetto. Il CLI utilizza i vari sdk delle singole piattaforme che vanno installati manualmente.

Installazione

Per installare cli di cordova è prima necessario scaricare ed installare node.js e poi eseguire:

sudo npm install -g cordova

npm è il package manager di node, l'opzione -g specifica di installare il pacchetto globalmente e cordova è il nome del pacchetto da installare.

Creazione di una applicazione

Con il comando

cordova create hello com.example.hello HelloWorld

cordova creerà la cartella hello contenente il progetto per l'applicazione con l'identificatore com.example.hello. La sottocartella www contiene i file html/css/javascript scritti dallo sviluppatore, e il file config.xml specifica i metadati necessari per la generazione e la distribuzione dell'applicazione. Il terzo parametro sarà il nome user-friendly dell'applicazione, se omesso viene utilizzato il nome HelloCordova.

Gestione delle piattaforme

Una volta nella cartella dell'applicazione è possibile gestire le piattaforme per le quali si intende fare il deploy attraverso il comando

cordova platform

seguito da un'opzione (add/rm) ed il nome della piattaforma. Per ottenere una lista delle piattaforme correntemente attive per il progetto basterà utilizzare l'opzione ls dopo il comando platform.

Per ogni piattaforma attiva verrà utilizzata una cartella nel path nomeProgetto/platforms/nomePiattaforma.

Build

Attraverso il comando

cordova build (nomePiattaforma)

verrà generato il codice specifico per ogni piattaforma attualmente attiva. Si può limitare il build ad una singola piattaforma, specificandone il nome dopo il comando build.

Test e Run

Laddove il produttore della piattaforma fornisca anche un emulatore/simulatore per desktop quest'ultimo può essere lanciato per testare l'applicazione attraverso il comando

cordova emulate nomePiattaforma

mentre per testare l'applicazione direttamente sul dispositivo fisico si utilizza

cordova run nomePiattaforma

Gestione Plugins

Come precedentemente spiegato, Cordova utilizza una architettura fortemente basata su plugin. Fino ad ora non è stato aggiunto nessuno, e quello che otteniamo è la possibilità di avere una normale applicazione web con il vantaggio di avere tutti i file in locale (potendo quindi funzionare anche in assenza di connettività) e resa disponibile come pacchetto per la piattaforma specifica.

Ma per poter sfruttare a pieno le potenzialità di Cordova e quindi poter accedere ad API native vediamo come aggiungere un plugin.

Apache ha creato un repository web nel quale cercare i plugin, per poter leggere una breve descrizione e la documentazione. Questo repository è disponibile al seguente indirizzo:

http://plugins.cordova.io/

Oltre ai plugin resi disponibili direttamente da Apache, è possibile trovare anche plugin di terze parti resi disponibili da sviluppatori. Il repository è nuovo, quindi non sono ancora presenti tutti i plugin sviluppati, per cui consiglio di fare una ricerca anche su github.com.

Una volta ottenuto l'identificativo di un plugin (ad esempio org.apache.cordova.camera) l'installazione è semplice, basterà utilizzare il comando

cordova plugin add “identificatore plugin”

Per rimuovere un plugin basta sostituire add con rm al comando qui sopra, è possibile ottenere una lista dei plugin correntemente attivi attraverso:

cordova plugin ls

 

Realizzazione di un Plugin

Un plugin è composto da un opportuno file contenente metadati chiamato plugin.xml, del codice Javascript, che esporrà le API utilizzabili dall'applicazione e opzionalmente del codice nativo. Il codice nativo è opzionale e nel caso sia assente il plugin è completamente realizzato in Javascript, e non potrà quindi utilizzare le API native fornite dal produttore della piattaforma.

Per comprendere meglio la anatomia di un plugin cordova riporterò come esempio (tratta dal libro Apache Cordova 3 Programming) un plugin che permette di ottenere il nome dell'operatore e il codice del paese in cui è il dispositivo.

Javascript

Attraverso la chiamata al metodo cordova.exec avviene il passaggio di controllo al codice nativo di ogni piattaforma, per cui il codice Javascript del plugin andrà ad invocare questo metodo.

Una volta che il codice nativo ha terminalo l'esecuzione invocherà una funzione di callback e restituisce il valore di ritorno all'oggetto Javascript. La signature completa del metodo exec è la seguente:

cordova.exec(successCallback, errorCallback, 'PluginObject', 'pluginMethod', [arguments])

I primi due parametri specificano che funzioni eseguire in caso di successo o errore lato codice Javascript, il parametro PluginObject è una stringa che identifica l'oggetto nativo che contiene il metodo richiesto specificato dal parametro pluginMethod. L'ultimo argomento opzionale è un array che contiene gli argomenti da passare al metodo nativo.

Il codice Javascript del plugin sarà:

var cordova = require('cordova');

var carrier = {

getCarrierName : function(successCallback, errorCallback) {

cordova.exec(successCallback, errorCallback, 'CarrierPlugin', 'getCarrierName', []);

},

getCountryCode : function(successCallback, errorCallback{

cordova.exec(successCallback, errorCallback, 'CarrierPlugin', 'getCountryCode', []);

}

};

module.exports = carrier;

L'ultima riga serve a rendere visibile l'oggetto carrier all'intero delle applicazioni che sono in esecuzione all'interno del container Cordova.

Java

Per implementare il plugin lato codice nativo su piattaforma Android occorre estendere la classe CordovaPlugin fornita da Cordova, e realizzare i metodi initialize() e execute().

Il primo serve a rendere il codice Java “aware” del container Cordova, mentre il secondo realizza il dispatch dei metodi e fornisce l'implementazione dei metodi richiedibili da Javascript.

Utilizzando quindi le API native fornite da Android, il plugin sarà realizzato come segue:

public class CarrierPlugin extends CordovaPlugin {

public static final String ACTION_GET_CARRIER_NAME = "getCarrierName";

public static final String ACTION_GET_COUNTRY_CODE = "getCountryCode";

public TelephonyManager tm;

public void initialize(CordovaInterface cordova, CordovaWebView webView){

super.initialize(cordova, webView);

Context context = this.cordova.getActivity().getApplicationContext();

tm = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);

}

public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {

try {

if (ACTION_GET_CARRIER_NAME.equals(action)) {

callbackContext.success(tm.getSimOperatorName());

return true;

}

else {

if (ACTION_GET_COUNTRY_CODE.equals(action)) {

callbackContext.success(tm.getSimCountryIso());

return true;

}

}

callbackContext.error("Invalid Action");

return false;

} catch (Exception e) {

System.err.println("Exception: " + e.getMessage());

callbackContext.error(e.getMessage());

return false;

}

}

}


Daniele Campogiani

Software Engineer