Una volta acquisita una foto sorge il problema di inviarla al server. Anche per questo aspetto Apache Cordova ci viene incontro con l'oggetto FileTransfer che ci consente di scambiare file via HTTP o HTTPS con un server remoto. Grazie al metodo upload()
possiamo inviare file al server e con download()
possiamo scaricare.
Vediamo quindi come sfruttare questo oggetto nella nostra applicazione per inviare al server insieme ai dati degli immobili le relative foto.
Purtroppo allo stato attuale non è supportato l'invio di più file nella stessa richiesta HTTP, quindi siamo costretti a modificare la modalità di invio delle schede prevedendo tante richieste HTTP quante sono le schede da inviare.
In generale questa è una scelta da evitare nel mondo mobile (ma non solo), preferendo limitare al minimo necessario le richieste HTTP al server sia per ottimizzare la banda disponibile, generalmente limitata, sia per ridurre il consumo di energia. Confidiamo nelle prossime release di Cordova per poter inviare al server tutte le schede in un'unica transazione.
Dunque, il nostro codice per l'invio delle schede assumerà la seguente forma:
$("#btnInviaSchede").on("tap", function() {
// ...
for (var i=0; i<app.storage.length; i++) {
scheda.load(app.storage.key(i));
scheda.send(onSuccessSend, onFailureSend);
}
// ...
}
Il metodo send()
dell'oggetto scheda
non prevede più un parametro per l'elenco delle schede da inviare ma soltanto le funzioni di callback per l'esito positivo e negativo dell'invio; esso invierà ora la sola scheda corrente, compresa la foto associata:
var scheda = {
data: { nome: "", indirizzo: "", descrizione: "", prezzo: "0,00", coordinate: {} },
photoURI: "",
// ...
send: function(successCallback, failCallback) {
var options = new FileUploadOptions();
options.fileKey = "foto";
options.fileName = this.photoURI;
options.params = this.data;
ft = new FileTransfer();
ft.upload(this.photoURI,
"http://www.backendserver.it/schedeImmobiliari",
successCallback,
failCallback,
options);
},
// ...
}
La prima cosa che viene fatta all'interno del metodo è la creazione di un oggetto FileUploadOptions
che conterrà i dettagli relativi all'invio che si sta per effettuare. Immaginando questo oggetto come una sorta di form da compilare, indichiamo tramite la proprietà fileKey
il nome dell'elemento della form a cui è associato il file e a fileName
il nome del file da inviare. Questo corrisponde in un certo senso a specificare un campo di tipo file su una form.
La proprietà params
consente di specificare coppie di chiave e valore da inviare al server insieme al file. Utilizziamo questa proprietà per specificare i dati testuali della scheda.
Una volta preparato il tutto, creiamo un oggetto FileTransfer
ed invochiamo il metodo upload()
passando l'URI del file da inviare, l'URL della pagina del server che elaborerà la richiesta, le funzioni di callback per gestire l'esito positivo o negativo dell'invio e le opzioni create prima.
In caso di esito positivo dell'invio verrà invocata la seguente funzione:
function onSuccessSend(result) {
if (result.responseCode == 200) {
} else {
navigator.notification.alert(
"Il server non ha potuto elaborare la scheda",
scheda.delete();
function(){},
"Errore");
}
}
Notiamo che per esito positivo in questo caso si intende che è stata effettuata correttamente la richiesta HTTP al server, non che il server abbia risposto positivamente ad essa. Infatti nella funzione analizziamo il codice HTTP di risposta del server e per decidere se eliminare la scheda o meno.
Se invece si è verificato un problema che ha impedito l'invio della richiesta HTTP al server sarà invocata la seguente funzione:
function onFailureSend(error) {
var message = "";
switch(error.code) {
case FileTransferError.FILE_NOT_FOUND_ERR:
messaggio = "Non è stato possibile trovare la foto associata alla scheda";
break;
case FileTransferError.INVALID_URL_ERR:
messaggio = "URL inesistente o errata";
break;
case FileTransferError.CONNECTION_ERR:
messaggio = "Errore di connessione";
break;
case FileTransferError.ABORT_ERR:
messaggio = "Trasferimento interrotto";
break;
}
navigator.notification.alert( messaggio, function(){}, "Errore");
}
Essa si limita ad interpretare il codice di errore del trasferimento ed a visualizzare il relativo messaggio.
Ad invio completato con successo non dimentichiamo di fare pulizia dei file temporanei associati alle foto chiamando il metodo navigator.camera.cleanup()
.