Diferència entre revisions de la pàgina «Cordova»

De Cacauet Wiki
Salta a la navegació Salta a la cerca
 
(Hi ha 6 revisions intermèdies del mateix usuari que no es mostren)
Línia 50: Línia 50:
 
** Com que surten chorrocientos missatges, és més clar si filtrem només els què ens interessa (tot i que en determinats moments ens pot interessar treure el filtre per veure-ho tot):<pre>$ ./platforms/android/cordova/log | grep CONSOLE</pre>
 
** Com que surten chorrocientos missatges, és més clar si filtrem només els què ens interessa (tot i que en determinats moments ens pot interessar treure el filtre per veure-ho tot):<pre>$ ./platforms/android/cordova/log | grep CONSOLE</pre>
 
** Potser la manera més còmoda seria posar-ho tot a la mateixa comanda:<pre>$ cordova run android ; ./platforms/android/cordova/log | grep CONSOLE</pre>
 
** Potser la manera més còmoda seria posar-ho tot a la mateixa comanda:<pre>$ cordova run android ; ./platforms/android/cordova/log | grep CONSOLE</pre>
 +
 +
<br>
 +
 +
== APIs, AJAX i CORS ==
 +
Les crides AJAX a les APIs del servidor en el nostre codi seran probablemnt imprescindibles. Però cal ajustar algunes coses perquè funcioni correctament.
 +
 +
CORS = Cross-Origin Resource Sharing
 +
 +
Els browsers tenen un sistema de protecció per no permetre crides entre dominis. En el nostre cas teniim una aplicació Cordova local (localhost) i una API en un servidor extern (localhost:8000 o en producció al domini pertinent). Per superar aquesta limitació hem de realtizar alguns canvis:
 +
 +
=== Client ===
 +
Afegir el següent codi al index.html (les 2 darreres línies amb "script-src" i "connect-src" les hem afegit a la plantilla original):
 +
<syntaxhighlight lang="xml">
 +
    <meta http-equiv="Content-Security-Policy" content="
 +
        default-src 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval';
 +
        style-src 'self' 'unsafe-inline';
 +
        media-src *;
 +
        img-src 'self' data: content:;
 +
        script-src * 'unsafe-eval' 'unsafe-inline';
 +
        connect-src * 'unsafe-eval' 'unsafe-inline';">
 +
</syntaxhighlight>
 +
 +
Fer la crida AJAX amb normalitat, per exemple amb jQuery '''suposant que el nostre server està a localhost:8080''':
 +
<syntaxhighlight lang="javascript">
 +
    $.ajax({
 +
        url:"http://localhost:8080/api/test",
 +
        dataType: 'json',
 +
        timeout: 5000,
 +
        success: function(data) {
 +
            alert("success");
 +
        } ,
 +
        error: function(data) { alert("fail"); }
 +
    });
 +
</syntaxhighlight>
 +
 +
O bé:
 +
<syntaxhighlight lang="javascript">
 +
    $.getJSON("http://localhost:8080/api/test", function( data ) {
 +
        alert("success status="+data["status"]);
 +
    }).fail( function(e) {
 +
        alert("error");
 +
        console.log(e);
 +
    });
 +
</syntaxhighlight>
 +
 +
=== Servidor ===
 +
Primer, en desenvolupament cal tenir cura de no solapar el servei de servidor (p.ex. Laravel a localhost:8000) amb el Cordova, que sol utilitzar el mateix port (localhost:8000). Per tant, convé engegar Laravel en un altre port, per exemple, el 8080:
 +
$ php artisan serve --port 8080 --host 0.0.0.0
 +
 +
Al costat del servidor cal activar un ''header'' per permetre que el client (JS) accedeixi a les dades. Els ''frameworks'' estan protegits per impedir aquests accessos, així que caldrà explicitar la directiva.
 +
 +
En Laravel per exemple, a <code>api.php</code>:
 +
<syntaxhighlight lang="php">
 +
Route::get('test', function(Request $request) {
 +
    $ret = array();
 +
    $ret["status"] = "OK";
 +
 +
    // Activem CORS
 +
    header("Access-Control-Allow-Origin: *");
 +
    // Enviem dades JSON
 +
    return $ret;
 +
});
 +
</syntaxhighlight>
 +
 +
Es pot sofisticar una mica més per no haver de fer aquesta línia de codi cada cop amb un Middleware:
 +
https://gist.github.com/technoknol/1a35ca4b150215f491d5c807940bd4ef
  
 
<br>
 
<br>

Revisió de 15:46, 11 abr 2018

Intro[modifica]

Cordova és un framework per desenvolupar aplicacions mòbils amb HTML + CSS + JavaScript. Té la gran avantatge que ens permet fer un codi únic per a totes les plataformes disponibles, particularment:

  • Android
  • iOS
  • Windows Phone
  • Ubuntu Touch
  • Blackberry
  • ...i el què vingui a darrera

El desavantatge és que podem trobar-nos amb que la performance és probra (velocitat d'execució de les aplicacions).

Si algun dia feu una aplicació i cobreu per ella, llegiu això atentament per pagar els impostos correctament.


Primeres passes[modifica]

  1. Instal·lar Android Studio.
    • Podriem només instal·lar les eines del SDK (comandes), però aquest programari ens facilitarà molt tot plegat.
    • Es pot instal·lar descarregant un tarball i executant-lo, però en general prefereixo instal·lar per comandes, és més fàcil actualitzar, etc.
      Instal·la Android Studio en Ubuntu 16.04 per comandes amb Ubuntu Make
    • Obre el SDK Manager del Android Studio i instal·la una API igual o superior a la del teu dispositiu físic. Si no tens cap dispositiu, pots instal·lar la que vulguis (al capdavall utilitzarem un emulador). Va bé utilitzar les darreres versions, però cal tenir en compte que potser no son tan estables com les "penúltimes versions".
  2. Instal·lar node.js. Podriem descarregar la darrera versió de la web, però ens serveix també la que hi ha als repositoris de Ubuntu:
    $ sudo apt-get install nodejs-legacy
  3. Instal·lar el gestor de paquets per a node.js NPM
    $ sudo apt-get install npm
  4. Actualitza tot el programari
    $ sudo npm -g update
  5. Instal·lar Cordova:
    $ sudo npm -g install cordova
  6. Crear projecte de prova:
    $ cordova create hellocordova
  7. Entrem a la carpeta de treball (hellocordova)
  8. Afegim les plataformes adequades. Primer podem provar amb "browser" per testejar:
    $ cordova platform add browser
  9. Llançem el projecte:
    $ cordova run browser

Aquesta serà una primera visualització en el navegador (normalment Google Chrome o Chromium). Convé reduir el tamany perquè sembli un mòbil i fer-nos a la idea del què desenvoluparem.

Si volem compilar-ho per Android:

  • Afegir plataforma:
    $ cordova platform add android
  • Compilar:
    $ cordova build android
  • Llençar emulador:
    $ cordova run android

Si endollem un dispositiu Android al nostre ordinador s'executarà en ell (si no ho fes, es pot provar afegint -device a la comanda run). L'emulador és pràctic quan no tenim un dispositiu a mà, però és força lent.


Depuració (debug)[modifica]

Per depurar el més fàcil és utilitzar al nostre codi missatges amb

console.log("missatge...")

Per poder mostrar aquests missatges dependrà de la plataforma que utilitzem:

  • browser: Premem F12 per veure el Inspector de Chrome, i anem a la pestanya "Console". També ens serà útil aquesta eina per poder depurar a nivell gràfic i CSS
  • Android:
    • Un cop llançada la app, executem:
      $ ./platforms/android/cordova/log
    • Com que surten chorrocientos missatges, és més clar si filtrem només els què ens interessa (tot i que en determinats moments ens pot interessar treure el filtre per veure-ho tot):
      $ ./platforms/android/cordova/log | grep CONSOLE
    • Potser la manera més còmoda seria posar-ho tot a la mateixa comanda:
      $ cordova run android ; ./platforms/android/cordova/log | grep CONSOLE


APIs, AJAX i CORS[modifica]

Les crides AJAX a les APIs del servidor en el nostre codi seran probablemnt imprescindibles. Però cal ajustar algunes coses perquè funcioni correctament.

CORS = Cross-Origin Resource Sharing

Els browsers tenen un sistema de protecció per no permetre crides entre dominis. En el nostre cas teniim una aplicació Cordova local (localhost) i una API en un servidor extern (localhost:8000 o en producció al domini pertinent). Per superar aquesta limitació hem de realtizar alguns canvis:

Client[modifica]

Afegir el següent codi al index.html (les 2 darreres línies amb "script-src" i "connect-src" les hem afegit a la plantilla original):

    <meta http-equiv="Content-Security-Policy" content="
        default-src 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval';
        style-src 'self' 'unsafe-inline';
        media-src *;
        img-src 'self' data: content:;
        script-src * 'unsafe-eval' 'unsafe-inline';
        connect-src * 'unsafe-eval' 'unsafe-inline';">

Fer la crida AJAX amb normalitat, per exemple amb jQuery suposant que el nostre server està a localhost:8080:

    $.ajax({
        url:"http://localhost:8080/api/test",
        dataType: 'json',
        timeout: 5000,
        success: function(data) {
            alert("success");
        } ,
        error: function(data) { alert("fail"); }
    });

O bé:

    $.getJSON("http://localhost:8080/api/test", function( data ) {
        alert("success status="+data["status"]);
    }).fail( function(e) {
        alert("error");
        console.log(e);
    });

Servidor[modifica]

Primer, en desenvolupament cal tenir cura de no solapar el servei de servidor (p.ex. Laravel a localhost:8000) amb el Cordova, que sol utilitzar el mateix port (localhost:8000). Per tant, convé engegar Laravel en un altre port, per exemple, el 8080:

$ php artisan serve --port 8080 --host 0.0.0.0

Al costat del servidor cal activar un header per permetre que el client (JS) accedeixi a les dades. Els frameworks estan protegits per impedir aquests accessos, així que caldrà explicitar la directiva.

En Laravel per exemple, a api.php:

 Route::get('test', function(Request $request) {
    $ret = array();
    $ret["status"] = "OK";
 
    // Activem CORS
    header("Access-Control-Allow-Origin: *");
    // Enviem dades JSON
    return $ret;
 });

Es pot sofisticar una mica més per no haver de fer aquesta línia de codi cada cop amb un Middleware:

https://gist.github.com/technoknol/1a35ca4b150215f491d5c807940bd4ef


GUI framework[modifica]

De cara a construir la interfície gràfica de la nostra aplicació tenim diverses opcions. Destaquem aquestes:

  • A pèl : podem construir a partir del HTML i JS planer. El projecte d'exemple que ve és una mostra. Al principi pot ser ràpid però a la llarga crear widgets una mica rics i eficaços serà molt costós. A part, la compatibilitat d'algunes instruccions JS per a diferents plataformes (Android/iOS/Windows) ens pot portar problemes. El més recomanat és utilitzar algun framework per a JS.
  • jQuery mobile : jQuery és el framework per a JS més estandaritzat, pel que adaptar-nos a jQuery mobile serà fàcil i ràpid.
  • Angular.js : el framework de Google és interessant, però la corva d'aprenentatge és lenta. Si t'atreveixes pots directament utilitzar ionic framework que no deixa de ser una fusió entre Cordova + Angular.js

Ja es veu que recomano jQuery mobile, oi? ;)

jQyuery mobile[modifica]

Per entrar en jQyuery mobile framework recomano instal·lar el paquet de NPM cordova-jquery que ens facilitarà començar amb diverses plantilles simples.

Instal·lació:

$ sudo npm -g install cordova-jquery

Afegir plantilla (des del directori de treball). Només cal executar la següent comanda i triar la plantilla en mode interactiu:

$ cordova-jquery

En particular convé mirar-se la plantilla "headerNavbar", ja que ens ofereix un exemple molt clar de com gestionar diverses pàgines amb un menú de navegació per canviar d'una a l'altra.

D'aquest framework cal destacar:


Emmagatzemament[modifica]

El més senzill i convenient és utilitzar el localStorage dels navegadors, per emmagatzemar dades persistents en format JSON, ja que ve integrat al propi JavaScript del navegador (o més aviat la webview) en què s'executa la nostra app.


Plugins[modifica]

Podeu buscar-ne aquí: https://cordova.apache.org/plugins/


Descàrrega de fitxers[modifica]

Hi 2 plugins que s'utilitzen per a això: File (permet accés a filesystem) i File Transfer (per descàrregues), però val a dir que fastrde-downloader ens ho resol tot molt més senzillament (els dos primers es fan prou complexe d'utilitzar), inclús descomprimeix Zips:

$ cordova plugin add cordova-plugin-fastrde-downloader

Penseu que si voleu utilitzar les imatges descarregades en el GUI (per evitar accedir a internet), cal resoldre diversos problemes:

  • Clarificar quina és la URL adequada per accedir a la imatge descarregada. Es pot saber si utilitzem:
    • fileEntry.toURL(): ens dona la URL tipus "file:///data/..." del filesystem
    • fileEntry.toInternalURL(): ens dóna la URL interna tipus "cdvfile://localhost/persistent/...". Aquesta és la que ens interessa per col·locar-la al SRC de les imatges del nostre HTML.
  • Posar cdvfile:// com a protocol a la whitelist. En config.xml, afegir:
    <allow-navigation href="cdvfile://*/*" />
  • Assegurar-vos que la vostra API/servei permet CORS (cross-domain calls), sinó potser refusa enviar la imatge o la info JSON