Per la realizzazione di un'app con Apache Cordova
vengono utilizzate le tecnologie Web standard: HTML, JavaScript e CSS. Infatti, se diamo uno sguardo alle cartelle generate dal comando create
che abbiamo visto nella scorsa puntata ne noteremo una denominata www
. All'interno di questa cartella c'è tutto quello che costituisce la nostra applicazione mobile:
Il comando create
genera lo scheletro di un'applicazione con gli elementi principali.
Al livello più alto vediamo la pagina index.html
che contiene il codice HTML della nostra applicazione. Nella cartella css
avremo i nostri fogli di stile mentre in img
metteremo le immagini e in js
il codice JavaScript.
Notiamo però alcuni elementi particolari. Abbiamo ad esempio la cartella res
destinata a contenere risorse specifiche per il mondo mobile come ad esempio l'icona associata alla nostra app.
Il file spec.html
e la cartella spec
rappresentano l'ambiente di testing proposto da Cordova
: Jasmine. La sua presenza tra i file dell'applicazione è un modo per invitarci a non dimenticare di realizzare gli unit test.
Notiamo infine il file config.xml
che contiene le impostazioni relative alla nostra app.
Per comprendere meglio gli elementi di questo puzzle analizziamo il contenuto dei file che troviamo nelle cartelle e che costituiscono una semplicissma applicazione: una piccola variante della classica Hello world
.
Hello Cordova
Apriamo il file index.html
con un editor di testo o con l'ambiente di sviluppo che abbiamo scelto. Il suo contenuto è il seguente:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name = "format-detection" content = "telephone=no"/>
<meta name="viewport"
content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width;" />
<link rel="stylesheet" type="text/css" href="css/index.css" />
<title>Hello Cordova</title>
</head>
<body>
<div class="app">
<h1>Apache Cordova</h1>
<div id="deviceready">
<p class="status pending blink">Connecting to Device</p>
<p class="status complete blink hide">Device is Ready</p>
</div>
</div>
<script type="text/javascript" src="cordova.js"></script>
<script type="text/javascript" src="js/index.js"></script>
<script type="text/javascript">
app.initialize();
</script>
</body>
</html>
Come possiamo vedere si tratta di una sorta di Hello world, una semplice applicazione che visualizza un messaggio lampeggiante "Connecting to Device"
fino a quando il framework non viene completamente caricato e diventa operativo. A quel punto viene visualizzato il messaggio "Device is Ready"
.
Analizziamo il codice per comprendere i punti rilevanti. Notiamo innanzitutto i riferimenti agli altri elementi contenuti nella cartella www
: il riferimento al foglio di stile css/index.css
ed il riferimento al file JavaScript js/index.js
.
Il riferimento al file cordova.js è quello che collega il nostro HTML all'anima del framework. Esso contiene il codice JavaScript che interfaccia la nostra applicazione con l'infrastruttura nativa realizzata da Apache Cordova
. Il suo contenuto dipende dalla specifica piattaforma mobile di riferimento, per cui non possiamo utilizzare ad esempio la versione di Android per iOS o viceversa. Per questo motivo, se utilizziamo l'approccio a riga di comando, non troveremo nella nostra cartella www
nessun file cordova.js
. Esso sarà aggiunto automaticamente in fase di preparazione dell'app sulla base alla piattaforma per cui stiamo compilando.
Il riferimento a cordova.js
nel codice HTML della nostra applicazione va inserito prima di qualsiasi riferimento ad altri file JavaScript, in modo da assicurarci di aver caricato il framework prima di utilizzarlo.
Il codice JavaScript che avvia la nostra applicazione è rappresentato da
app.initialize();
Apriamo index.js
per vedere a cosa corrisponde questa inizializzazione. Il codice JavaScript contenuto nel file è mostrato di seguito:
var app = {
initialize: function() {
this.bind();
},
bind: function() {
document.addEventListener('deviceready', this.deviceready, false);
},
deviceready: function() {
app.report('deviceready');
},
report: function(id) {
console.log("report:" + id);
// hide the .pending <p> and show the .complete <p>
document.querySelector('#' + id + ' .pending').className += ' hide';
var completeElem = document.querySelector('#' + id + ' .complete');
completeElem.className = completeElem.className.split('hide').join('');
}
};
Esso dichiara una variabile app
che rappresenta un oggetto con quattro metodi: initialize()
, bind()
, deviceready()
e report()
. Concettualmente essi rappresentano quattro fasi dell'avvio di un'applicazione:
Fase | Descrizione |
---|---|
Inizializzazione | È la fase nel corso della quale vengono effettuate tutte le operazioni preliminari come ad esempio l'assegnamento di variabili globali. Nel nostro caso l'unica attività che eseguiamo è l'invocazione della fase successiva tramite il metodo bind() . |
Preparazione | In questa fase vengono effettuate le attività di preparazione del funzionamento dell'applicazione come ad esempio la definizione dei gestori di eventi. Nel nostro esempio definiamo il gestore dell'evento deviceready assegnandogli il metodo omonimo della nostra app. L'evento deviceready è fondamentale nello sviluppo di applicazioni Cordova : il verificarsi di questo evento garantisce che il framework è stato correttamente caricato e le API per interfacciarsi al dispositivo sono pronte per essere utilizzate. |
Disponibilità | Questa fase si verifica quando le API mobile sono disponibili e pronte all'uso. Da qui in poi possiamo avviare le attività specifiche della nostra app. Nel codice d'esempio ci limitiamo a chiamare il metodo report() della nostra app. Da notare come in questo caso invochiamo il metodo facendo riferimento alla variabile app e non a this come è avvenuto nelle fasi precedenti. Questo perchè siamo all'interno di un gestore di evento ed il contesto di esecuzione è diverso. |
Comunicazione | In questa fase l'applicazione interagisce con l'utente. Nel nostro caso ci limitiamo a nascondere il messaggio Connecting to Device e a rendere visibile il messaggio Device is Ready . |
Configuriamo l'app
Al codice HTML e JavaScript che abbiamo visto è necessario aggiungere alcune informazioni di configurazione per la nostra applicazione mobile. Si tratta di meta-informazioni descrittive ed operative per pacchettizzare la nostra app e renderla fruibile all'interno del dispositivo mobile. Queste informazioni sono contenute nel file di configurazione config.xml.
La struttura dell'XML è basata sullo standard W3C Packaged Web Apps (Widgets) e prevede numerose opzioni. In questa fase ci limiteremo a dare un'idea del suo contenuto rimandando ad un altro momento l'analisi delle opzioni più comuni man mano che ne avremo bisogno.
Aprendo il file config.xml dell'applicazione d'esempio noteremo alcuni elementi autoesplicativi, come ad esempio
<name>appTest</name>
<description>
A sample Apache Cordova application that responds to the deviceready event.
</description>
<author email="callback-dev@incubator.apache.org" href="http://cordova.io">
Apache Cordova Team
</author>
Come è evidente si tratta della descrizione della nostra app e dei riferimenti di chi l'ha sviluppata.
Gli elementi successivi rappresentano dettagli grafici come l'icona da associare all'app e lo splashscreen da visualizzare durante l'avvio sul dispositivo:
<icon height="512" src="res/icon/cordova_512.png" width="512" />
<icon cdv:platform="android" height="96" src="res/icon/cordova_android_96.png" width="96" />
<icon cdv:platform="blackberry" height="80" src="res/icon/cordova_bb_80.png" width="80" />
<icon cdv:platform="ios" height="144" src="res/icon/cordova_ios_144.png" width="144" />
<cdv:splash cdv:platform="android" height="480" src="res/screen/android_hdpi_landscape.png" width="800" />
<cdv:splash cdv:platform="android" height="800" src="res/screen/android_hdpi_portrait.png" width="480" />
...
<cdv:splash cdv:platform="blackberry" height="300" src="res/screen/blackberry_transparent_300.png" width="300" />
<cdv:splash cdv:platform="blackberry" height="200" src="res/screen/blackberry_transparent_400.png" width="200" />
<cdv:splash cdv:platform="ios" height="748" src="res/screen/ipad_landscape.png" width="1024" />
<cdv:splash cdv:platform="ios" height="1004" src="res/screen/ipad_portrait.png" width="768" />
...
<cdv:splash cdv:platform="winphone" height="800" src="res/screen/windows_phone_portrait.jpg" width="480" />
Come possiamo vedere, gli elementi XML puntano alle immagini che si trovano sotto la cartella res
. Inoltre sono state specificate versioni diverse delle icone in base alla specifica piattaforma. Per lo splashscreen abbiamo versioni diverse anche in base alle dimensioni e all'orientamento dello schermo.
Nel file config.xml
possiamo trovare altri elementi XML che hanno particolari significati.
Ad esempio, tramite uno o più elementi <feature>
indichiamo il supporto di una funzionalità del dispositivo come requisito per l'operatività dell'app mentre tramite elementi <preference>
possiamo specificare opzioni di configurazione dipendenti dalla piattaforma mobile. Avremo modo di approfondire l'argomento strada facendo.
Il primo esempio in esecuzione sull'emulatore
Abbiamo quindi approntato la nostra semplice prima app e siamo impazienti di vederla girare sul nostro dispositivo. Lanciamo la compilazione nell'ambiente di sviluppo scelto. Nel caso di compilazione a riga di comando lanciamo il comando:
cordova build
Questo genererà il pacchetto compilato per la piattaforma o le piattaforme mobile di riferimento.
Per vedere l'app in esecuzione proviamo a lanciare l'emulatore. Ad esempio tramite il comando
cordova emulate android
lanceremo l'emulatore Android ed otterremo una schermata analoga alla seguente:
La nostra prima app non fa molto ma funziona ed è servita ad esplorare i principi di base della realizzazione di app ibride con Apache Cordova
.
Organizzazione del codice
Come abbiamo avuto modo di vedere, l'esempio di app Hello Cordova
propone un certo modo di organizzare il codice JavaScript. Naturalmente questo non è l'unico modo. Esso rappresenta il modello di organizzazione del codice proposto dal team di sviluppo di Apache Cordova
. Ognuno può adottare l'approccio che ritiene più adatto alle proprie esigenze, talvolta dettate dal particolare framework JavaScript utilizzato. Ad esempio, se usiamo jQuery
potremmo riscrivere il codice di inizializzazione dell'applicazione nel seguente modo per assicurarci che jQuery
sia stato caricato:
$(document).ready(function() {
app.initialize();
});
L'importante è aver chiari i concetti di base: impostare il riferimento a cordova.js
prima di qualsiasi altro riferimento a file JavaScript ed utilizzare le API di Cordova dopo il verificarsi dell'evento deviceready
.