Apache Cordova (inicialment PhoneGap) son unes llibreries per al desenvolupament d'apps mòbils utilitzant JavaScript, HTML i CSS. La principal avantatge és que permet utilitzar un llenguatge web genèric (JS) i compilar l'app per a diverses plataformes diferents, d'entre les que destaquem les majoritàries Android i iOS.
El seu funcionament es basa en tenir una aplicació nadiua amb una simple WebView que ocupa tota la pantalla sencera. Implementant codi JavaScript dins la WebView ens permetrà controlar la interfície gràfica. Per accedir a les funcionalitats pròpies del dispositiu mòbil disposarem de certes llibreries (càmera, filesystem, acceleròmetre, etc).
Per poder seguir aquest article se suposa que has de tenir coneixements de JavaScript, HTML i CSS.
Si tens coneixements molt bàsics també t'interessaria repassar els conceptes del DOM o Document Object Model.
Abans de començar a treballar amb Cordova caldrà que tinguem instal·lats els entorns de desenvolupament: llegeix Java i Android primerament.
Per instal·lar Cordova necessites un bon plegat d'eines. De forma general necessitaràs:
Segueix les indicacions de l'article Cordova install per posar a punt tot l'entorn.
Si ja tens l'entorn preparat, es tracta de desenvolupar una app com si es tractés d'una aplicació web (com si fos pel browser) amb JavaScript. Podem aplicar llibreries típiques com jQuery o AngularJS, i a més disposarem d'algunes mes per a poder accedir al hardware del mòbil.
La seqüència típica per iniciar un projecte és com s'indica a continuació:
$ cordova create proj1
$ cd proj1
$ cordova platform add android
$ cordova build android
$ cordova run android
Tingues en compte que per desenvolupar resulta molt còmode treballar amb la platform browser i les eines de desenvolupador del propi navegador.
Mira l'article Introducció Javascript i realitza l'exercici de login i registre d'usuaris dins d'una aplicació Cordova.
jQuery és una biblioteca de codi que opera sobre el DOM de JavaScript i facilita moltes operacions.
Podeu aprendre més sobre jQuery ← en aquesta wiki.
Implementarem una tasklist clàssica. Inicialment farem una versió senzilla que permeti afegir elements i prou.
Tasklist:
Continua de l'anterior exercici Tasklist v0.1:
jQuery.onclick=«elimina()» del botó, assigneu-la d'aquesta manera, que és la bona pràctica recomanada en general:$(".boto_eliminar").click(elimina);
On elimina és la funció que cridarem per esborrar l'element.
function elimina(event){ var caller = event.target || event.srcElement; console.log( caller ); }
<li> (si no, esborraràs el botó i prou).Dialog de jQuery UI per demanar l'usuari que entri el nou text.<li> que volem editar i creant a dins un <input> i botó de OK com a la imatge. Després caldrà agafar el text i ficar-ho dins l'element de la tasca.
localStorage és un objecte built-in de JavaScript dintre dels browsers que ens permet emmagatzemar dades persistents en una BD interna del tipus KEY-VALUE.
Les aplicacions web no estaven pensades per emmagatzemar dades, només per ser visualitzades, i en tot cas per interaccionar amb el servidor. Per això aquest recurs va trigar en implementar-se en els navegadors. A més, cal tenir en compte que, per raons de seguretat, l'accés al disc dur en un navegador sempre s'ha limitat molt (JavaScript no té accés al filesystem per seguretat de les dades de l'usuari).
És molt senzill d'utilitzar, al capdavall una DB key-value no deixa de ser un diccionari. En principi en tindreu prou amb els mètodes:
localStorage.setItem("clau","valor"); var valor = localStorage.getItem("clau");
Mira't la doc de W3Schools per mes detalls.
localStorage només emmagatzema strings. Si volem guardar objectes complexes, com diccionaris o arrays, caldrà utilitzar algun mètode de serialització. Les funcions típiques que s'empren per a això son:
localStorage.
Aplicarem tot l'exposat fins aquí en el següent exercici:
Fes la tasklist persistent utilitzant el localStorage, tal i com s'explica més amunt.
Cordova ens deixa crear qualsevol pàgina HTML amb el codi que ens sembli bé. Però si ens fixem en la plantilla al crear de zero un projecte, ens trobem algunes particularitats que cal parar atenció, sobretot el tag META amb el Content-Security-Policy:
<meta http-equiv="Content-Security-Policy" content="default-src 'self' data: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *; img-src 'self' data: content:;">
Aquest tag META bàsicament ens limita certes accions de l'HTML que podrien fer vulnerable el nostre codi. Entre d'altres, no ens deixa connectar a webs externes si no les validem dins del tag. I tampoc ens permet posar codi inline.
Típicament podríem fer una aplicació en JavaScript en una pàgina HTML i podríem posar botons que cridin a funcions del nostre codi amb un onclick (el què coneixem per crida inline). Doncs bé, Cordova no ens deixa fer inlines com aquest:
Aquesta solució funcionaria en una web normal, però no funciona si posem el tag META de Content-Security-Policy:
<button id="boto_esborrar" onclick="esborra()">Esborra</button>
Forma de solventar-ho: fer els botons més senzills, sense onclick (però amb id):
<button id="boto1">Prem per afegir</button> <!-- al final del body carreguem les llibreries de Cordova i la de la nostra app --> <script src="cordova.js"></script> <script src="js/index.js"></script>
I després, en el nostre index.js, ja li afegim el onclick per cridar la funció addElem:
document.getElementyById('boto1').onclick(addElem);
$('#boto1').click(addElem);
Abans d'executar codi JavaScript sol convenir esperar a que estigui carregat tot el document. Tenim 2 estratègies bàsiques:
<script src=… al final del document HTML.
Estil jQuery amb la funció ready:
$(document).ready( function () { // inicialitzar: assignar events $('#addButton').click(addElem); $('#apiButton').click(callAPI); });
function inicialitza() { // inicialitzar: assignar events document.getElementById("addButton").onclick = addElem; document.getElementById("apiButton").onclick = callAPI; } // associem l'event "onload" del document a la funció inicialitza window.addEventListener("load", inicialitza, false);
Cordova necessita inicialitzar el hardware del dispositiu. Per això és important que al nostre codi carreguem les llibreries. Si és una aplicació com la tasklist que només dibuix per pantalla segurament no li caldria. Però si volem accedir a la càmera o al sistema d'arxius del dispositiu serà imprescindible carregar aquestes llibreries:
<body> ... <!-- carreguem les llibreries de Cordova i la de la nostra app --> <script src="cordova.js"></script> <!-- dispara event ondeviceready --> <script src="js/index.js"></script> </body>
La línia del HTML que carrega cordova.js dispararà un event «ondeviceready» propi de Cordova. Al nostre codi podem començar a realitzar accions quan es rebi aquest event:
document.addEventListener('deviceready', onDeviceReady, false); function onDeviceReady() { // aquí ja podem fer accions amb la càmera, arxius, etc. }
Fes una versió v0.4 de la Tasklist aplicant el tag META de seguretat i les inicialitzacions pertinents.
MaterializeCSS és un framework CSS per crear interfícies atractives i responsives.
És molt important comptar amb una interfície gràfica clara i agradable si volem que la nostra app tingui una bona experiència d'usuari (UX).
La responsiveness és la capacitat de les interfícies d'amotllar-se a diferents grandàries de pantalles, per exemple, un mòbil, una tablet, depenent de si estan en vertical (portrait) o apaïsades (landscape). És una de les principals utilitats dels frameworks CSS.
Segueix aquest tutorial sobre Materialize per iniciar un nou projecte Cordova amb aquesta eina.
Treballar aplicacions en HTML+JS accedir a dades externes és molt còmode utilitzant crides asíncrones amb AJAX.
Una API web, també conegut com a web service és una interfície via web per demanar dades, així que es podria considerar una crida remota, d'aquí que en diguem API, com les llibreries de programació.
Explorarem la API externa per accedir a dades de www.musicbrainz.org
musicbrainz.org és una web amb informació sobre grups musicals que disposa d'una API pública o web service. Ens anirà molt bé per fer els primers exemples d'accés a dades remotes.
Documentació de musicbrainz:
Obtenir els resultats en XML dels grups amb «queen» al seu nom:
curl https://musicbrainz.org/ws/2/artist?query=queen
Per obtenir els resultats en format JSON cal afegir un header a la request de la query, per exemple:
curl https://musicbrainz.org/ws/2/artist?query=queen -H "Accept:application/json"
Si volem mostrar els resultats de forma mes clara en la shell, podem utilitzar una eina per tenir una correcta indentació:
curl ...url_query... | python -m json.tool
Un altre exemple per cercar la informació d'un artista concret. De qui estem parlant?…
curl -H 'Accept:application/json' http://musicbrainz.org/ws/2/artist/5b11f4ce-a62d-471e-81fc-a69a8278c7da | python3 -m json.tool
Aquestes mateixes les podem demanar des d'un document/aplicació HTML+JS amb crides asíncrones, el que solem conèixer per AJAX. Utilitzarem AJAX amb jQuery que ens ajudarà a simplificar el codi. Els exemples estan a la mateixa documentació, però us poso aquí un d'essencial per fer la crida i que ens retorni un objecte JSON de la API de musicbrainz.org :
$.ajax({ method: "GET", url: "https://musicbrainz.org/ws/2/artist?query=queen", dataType: "json", // necessitem això pq ens retorni un objecte JSON }).done(function (msg) { for(let item in msg.artists) { console.log(msg.artists[item]); // aquí caldría fer mes coses, of course... // ... }; }).fail(function () { alert("ERROR"); });
Cal tenir en compte que les URLs a les que cridis amb AJAX han de tenir habilitada la capçalera de CORS (Cross-Origin Resource Sharing). Les APIs solen tenir-ho habilitat. Totes les APIs públiques ho tenen activat.
Pots veure una demo i explicació de com funciona a http://ieti.cat/cors/
Aquí s'explica els orígens de CORS força correctament.
Dins la nostra aplicació cal autoritzar l'accés a les dades externes del domini en qüestió. Si no ho fem, ens apareixerà un error a la consola similar a:
Content Security Policy: Els paràmetres de la pàgina han blocat la càrrega d'un recurs a https://musicbrainz.org/ws/2/ («default-src»).
Per tal d'autoritzar la petició, caldrà que a la capçalera META amb la política de seguretat validem la font de dades als següents apartats:
data: https://musicbrainz.org : URLs de les APIs de les que vulgui rebre info.img-src: * : ens permetrà carregar imatges de qualsevol web.<meta http-equiv="Content-Security-Policy" content="default-src 'self' https://fonts.gstatic.com https://code.jquery.com data: https://musicbrainz.org gap: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' https://fonts.googleapis.com 'unsafe-inline'; media-src *; img-src * 'self' data: content:;">
Rock band searcher:
curlEn aquest repositori hi ha un llistat de public APIs per poder fer aplicacions amb les seves dades.
Mira't la documentació d'aquesta de space news ja que és força clara per començar.
Fes-li un cop d'ull i troba el teu hobby en una API!
Aprofitant el codi que hem fet amb l'API de musicbrainz.com , fes una nova app que utilitzi la API de spaceflight news:
var elems = document.getElementsByClassName('tabs'); var instance = M.Tabs.getInstance(elems[0]); instance.select('test-swipe-2');
Pots explorar-ne més a la documentació de plugins de Cordova.
Per depurar el més fàcil és utilitzar al nostre codi missatges via la consola del browser:
console.log("missatge...")
Per poder mostrar aquests missatges dependrà de la plataforma que utilitzem:
Chrome disposa d'eines de connexió remota. La consola de la WebView que utilitza la nostra app Cordova és accessible des de Chrome excecutat a la màquina host.
Obrim Chrome i anem a:
chrome://inspect/#devices
Des d'aquí hauriem de veure el nostre device i accedir-hi amb un inspect. S'obrirà una pantalla on veurem la consola de JavaScript.