Questo articolo è un'esplorazione di protocolli di servizi Web, formati di interscambio di dati comuni e best practice. Se sei interessato a creare applicazioni mobili performanti che si collegano al web, continua a leggere!
Selezionare un protocollo appropriato e un formato di interscambio dati per passare i dati tra la tua app mobile e la rete è una delle decisioni più importanti da prendere durante il processo di sviluppo. I protocolli più comuni e ampiamente utilizzati sono REST, XML-RPC e SOAP.
Tutti questi protocolli trasportano i dati tramite il protocollo HTTP. I protocolli XML-RPC e SOAP sono basati su XML, mentre i servizi REST possono contare su diversi formati di dati, i due più comuni sono XML e JSON. In particolare, SOAP è ampiamente apprezzato e adottato dalle applicazioni aziendali perché applica rigorosamente i modelli di dati e descrive le interfacce pubbliche tramite WSDL, rendendo così alcuni strumenti di sviluppo (come Microsoft Visual Studio per .NET) in grado di impostare automaticamente oggetti e metodi per consumare i servizi semplicemente aggiungendo un riferimento al servizio WSDL al progetto.
XML, tuttavia, è un progetto meno efficiente di JSON quando opera in uno scenario di rete limitato a larghezza di banda come lo sviluppo mobile. Le reti dati mobili (WWAN) sono solitamente meno affidabili delle reti cablate (LAN) o wireless (WLAN) perché i clienti in movimento possono facilmente entrare ed uscire dalle aree di copertura. Inoltre, alcuni utenti non si iscrivono a piani dati "piatti" e vengono effettivamente addebitati dal traffico di rete.
Quindi, mentre stai sviluppando per i dispositivi mobili dovresti sempre optare per la semplicità e la riduzione del traffico.
Confrontiamo il semplice XML con JSON con una risposta di esempio:
XML
Ciao, dispositivo!
JSON
returnValue: "Ciao, dispositivo!"
Come potete vedere, JSON trasporta un carico utile più piccolo perché ha solo bisogno di racchiudere i suoi dati con parentesi (ricci per oggetti, quadrati per matrici) e virgolette, mentre XML richiede un nodo radice completo e tag di apertura-chiusura per ogni elemento o gruppo. Il salvataggio su tali tag può ridurre in modo significativo il carico utile della risposta e maggiore è il numero di dati che si trasferiscono, maggiore sarà il riempimento del payload con XML.
Inoltre, SOAP e XML-RPC richiedono strutture dati XML più complesse (come la "busta" SOAP), aggiungendo ulteriore peso al carico utile.
Per questo motivo, consiglio di scegliere JSON per il formato di interscambio dati della tua app e RIPOSO per il protocollo di trasferimento a meno che XML, SOAP o XML-RPC siano esplicitamente richiesti per le tue esigenze. Se è necessario applicare un modello di dati, è possibile farlo anche con JSON utilizzando lo schema JSON o WSDL 2.0.
Per riferimenti e ulteriori informazioni sui protocolli discussi e sui formati dei dati, controlla quanto segue:
Poiché la maggior parte dei servizi Web opera su reti pubbliche, la protezione dei dati che verranno scambiati tra i servizi e l'app è uno dei problemi più critici che è necessario affrontare. Molti servizi Web forniscono funzionalità remote agli utenti autenticati, pertanto è necessario trasferire i dati e le credenziali di autenticazione degli utenti privati anche in rete.
Dati personali, dati dell'account e credenziali dovrebbero mai viaggiare in forma di testo in chiaro su una rete pubblica, quindi questo significa che i servizi Web e le app devono implementare la crittografia. La buona notizia è che i protocolli più comuni trasportano i dati su HTTP, quindi puoi fare affidamento sul ben noto, affidabile e robusto Protocollo HTTP SSL / TLS (HTTPS) che gode di un ampio supporto sia lato server che lato client.
Abilitare SSL su server web comuni è abbastanza facile (ci sono molte risorse utili per Apache, IIS e Nginx). Tutto quello che devi fare è acquistare un certificato SSL e configurarlo sul tuo server. In un nella peggiore delle ipotesi, potresti anche emettere un certificato autofirmato che ti porterà la crittografia gratuita, ma lo farei non consiglio di farlo. Alcune CA rilasciano certificati a basso costo, e i vantaggi che si ottengono lavorando con un certificato firmato e attendibile valgono il costo aggiuntivo (ovvero impedendo attacchi man-in-the-middle utilizzando l'infrastruttura PKI). L'utilizzo di certificati autofirmati potrebbe richiedere anche una codifica aggiuntiva o persino "hack" specifici dell'applicazione, dal momento che alcune librerie di rete rifiuteranno connessioni HTTPS non sicure (controlla questi articoli su Android, n. 1 e n. 2 e su iOS).
Abilitare SSL sul lato client è un gioco da ragazzi: i linguaggi di programmazione comuni in genere dispongono di classi e librerie HTTP che forniscono il supporto nativo HTTP-SSL e "automagicamente" si occupano della crittografia semplicemente utilizzando URL "https: //" anziché "http : // "URL da utilizzare per i servizi Web.
Se si sceglie un certificato SSL a basso costo, assicurarsi che i dispositivi e i sistemi operativi che si desidera sviluppare abbiano il certificato radice CA emittente in dotazione, altrimenti non si fideranno del certificato.
Non dovresti mai chiedere agli utenti di applicare patch, alterare o hackerare i loro sistemi per far funzionare le tue app, e se lo fai, non aspettarti che molti di loro si adeguino.Le transazioni dei servizi Web sono pensate per essere atomico, interoperabile e scalabile, quindi i servizi Web sono di solito apolide (controlla questa discussione interessante sul significato di connessioni "senza stato").
Molti servizi Web forniscono funzionalità relative all'utente e accesso a informazioni sensibili. Naturalmente, farlo richiede l'autenticazione. Poiché tali transazioni sono prive di stato, tradizionalmente era necessario firmare le richieste con una chiave specifica dell'utente, fornendo l'autenticazione con ogni chiamata di metodo remota. Anche quando si trasferiscono dati su HTTPS, le credenziali dell'utente sono maggiormente a rischio quando vengono trasmesse su una rete pubblica. La crittografia a volte viene interrotta.
Questo dilemma è dove l'autenticazione basata su token come OAuth è utile. Utilizzando l'autenticazione basata su token, è necessario inviare le credenziali di un utente una sola volta. Se l'utente viene autenticato correttamente, verrà fornito con token che possono essere utilizzati per autenticare le successive chiamate ai metodi remoti.
La validità di un token si estende per un periodo di tempo limitato e può essere revocata in qualsiasi momento dal suo emittente (vale a dire lato server). Con l'autenticazione basata su token, è anche possibile condividere le stesse credenziali utente tra diverse app e servizi senza i servizi / app collegati mai conoscendo le reali credenziali dell'utente. Inoltre, questo metodo di autenticazione mantiene in modo sicuro una cache locale delle credenziali sul dispositivo dell'utente, in modo che l'utente possa essere "ricordato" e non dovrà autenticarsi ogni volta che utilizzerà l'app (digitare password complesse sui palmari può essere una vera dolore e può danneggiare seriamente recensioni di app).
OAuth è il framework di autenticazione basato su token più comune ed è stato adottato da grandi player come Google, Twitter, Facebook e così via. Consentendo agli utenti di riutilizzare i loro account esistenti, saltando i fastidiosi moduli di registrazione e mantenendo il controllo sull'accesso ai loro dati personali, puoi aumentare significativamente la tua base di utenti.
Alcuni provider OAuth richiedono che il proprio SDK venga importato nelle tue app per abilitare l'autenticazione, altrimenti ci sono molte librerie OAuth già pronte che puoi collegare alla tua app. Ci sono anche framework come oauth-php disponibili per creare provider OAuth personalizzati.
Suggerirei segnaletica come libreria client OAuth per Android e oauthconsumer per iOS.
Tutte queste librerie hanno esempi utili e sono facili da implementare. Tuttavia, la creazione delle sorgenti dei segnali sul tuo computer o l'importazione delle stesse nella tua app può essere un po 'un problema, ma in realtà non è necessario passare attraverso questo processo. Invece, puoi semplicemente importare i binari JAR nel tuo progetto e dovresti essere impostato. Su iOS, sarebbe simile all'importazione di una libreria statica (file * .a) nel progetto.
Il metodo di autenticazione più comune per i servizi basati su SOAP è un'estensione SOAP denominata Autenticazione di base HTTP (talvolta denominata Autenticazione del digest). Questa è una procedura standard ben supportata che è integrata in tutti i server Web più comuni come Apache, Nginx e IIS. Si basa su una coppia nome utente-password che deve essere inviata al server tramite le intestazioni HTTP.
Normalmente, non dovrai implementare manualmente l'autenticazione di base nelle tue applicazioni, poiché è ampiamente supportata anche nei più comuni linguaggi di programmazione. Il framework .NET si basa sulla classe NetworkCredential per fornire credenziali di autenticazione di base e digest alle richieste HTTP, PHP lo supporta tramite cURL e Java tramite Authenticator.
Se devi implementare Autenticazione di base, devi solo aggiungere questa intestazione alle tue richieste:
Nome utente di base: password
I valori "username" e "password" devono essere base64-encoded.
Si prega di notare che L'autenticazione di base HTTP viene utilizzata al meglio in combinazione con il protocollo HTTPS, mentre trasferisce le credenziali in testo in chiaro modulo. Digest Auth è un po 'più sicuro, perché in realtà hash il valore della password, ma HTTPS è raccomandato comunque per evitare gli attacchi hash bruteforce.
Maggiori dettagli e specifiche su questo argomento sono disponibili nel memo IETF RFC 2617.
Quando si sceglie un metodo di autenticazione o si integrano servizi ben noti (come i social network), è necessario tenere conto anche delle librerie native che sono integrate in molte piattaforme avanzate come iOS e Android. Questo può farti risparmiare molto tempo e molte righe di codice.
Android fornisce una buona struttura per centralizzare la gestione degli account degli utenti, la classe AccountManager. La guida ufficiale per sviluppatori Android fornisce una buona documentazione per questa classe, insieme ad alcuni suggerimenti per integrare OAuth 2 o scrivere il proprio "Tipo di account personalizzato".
Con iOS 6, Apple ha introdotto un nuovo Social Framework per integrare servizi importanti come Twitter, Facebook e Sina Weibo a livello di sistema operativo. Anche se non è necessario integrare questi servizi nella tua applicazione, potresti trovare un modo adatto per sfruttare i metodi di autenticazione incorporati tramite la personalizzazione.
Durante lo sviluppo per le applicazioni mobili, è importante mantenere i carichi di dati più bassi possibile. Questa sezione discuterà diverse strategie per farlo.
Compressione ZIP può ridurre significativamente il testo e anche il peso dei dati binari ed è ben supportato sulla maggior parte delle piattaforme, quindi usatelo bene se avete bisogno di trasferire grandi quantità di dati su reti mobili. Sono disponibili librerie utili per la gestione dei file ZIP per Android (ad es. Decompress) e iOS (ad esempio Ziparchive).
Se hai bisogno di trasmettere contenuti audio / video alle tue app mobili, scegli piattaforme di streaming avanzate che consentano loro di scalare flussi in base alle prestazioni della rete / dispositivo, come il protocollo HTTP Live Streaming (HLS) di Apple. In caso contrario, favorire la reattività rispetto alla qualità dei media è solitamente una buona scelta. Gioca con diversi compressori e impostazioni video e audio, ottimizzando il più possibile. È anche possibile raggruppare i dispositivi per tipo (palmari con schermo piccolo, palmari a schermo ampio e tablet) e fornire contenuti diversi per ogni tipo.
Molti dispositivi mobili sono dotati di display HD, ma i contenuti HD su schermi piccoli valgono davvero l'overhead della larghezza di banda extra? Sii onesto sull'importanza della qualità dei media nelle tue app e cerca di trovare il miglior equilibrio tra qualità e peso.
Supponiamo che tu debba codificare un'app reader per un giornale online. Prima di tutto, dovresti sempre lasciare che i tuoi utenti operino offline quando possibile. Mentre alcune app richiedono sempre una rete attiva (ad esempio i servizi di messaggistica), molte altre persone dovrebbero utilizzare la rete solo per scaricare pacchetti di dati e memorizzarli nella cache sul dispositivo.
Ciò migliorerà le prestazioni delle applicazioni, farà risparmiare denaro agli utenti su piani dati mobili non flat e renderà l'app utilizzabile quando la rete non è disponibile (ad esempio durante il volo).
Quando si scaricano contenuti su dispositivi che montano spazio di archiviazione esterno (ad esempio schede di memoria), è necessario consentire agli utenti di scegliere dove archiviare il contenuto scaricato (ad esempio, memoria interna o esterna) o semplicemente preferire lo spazio di archiviazione esterno. I dispositivi entry level solitamente dispongono di una memoria interna piuttosto piccola e possono diventare instabili o lenti quando la memoria interna è piena. Se le tue app occupano molto spazio di archiviazione, è probabile che vengano disinstallate per risparmiare spazio.
Torniamo all'esempio dell'app reader. Ogni articolo è un pezzo unico e sebbene gli articoli possano essere collegati tra loro, non c'è motivo per cui non si debba consentire agli utenti di iniziare a leggere gli articoli anche mentre il contenuto aggiuntivo è ancora in fase di download. Quindi, impacchetta i file di ciascun articolo (testo, immagini, allegati e supporti) archivi ZIP separati e fornire un metodo di servizio web per l'app per recuperare il elenco degli articoli disponibili. Chiedi alla tua app di scaricare pacchetti ZIP uno per uno e quindi renderli disponibili nell'app non appena ognuno è stato scaricato e mentre altri vengono scaricati in background. Si tratta di un grande miglioramento delle prestazioni e dell'esperienza utente rispetto all'attesa fino a quando l'intero payload non è stato scaricato! Puoi anche consentire agli utenti di scegliere quali pacchetti scaricare o meno (consentendo loro di risparmiare spazio, tempo e traffico) e consentire loro di rimuovere singoli pacchetti per risparmiare spazio di archiviazione senza rimuovere l'intera app.
Quanto segue è una risposta dall'app del server demo in bundle con questo articolo:
apiversion: 1, status: 0, packages: [file: "pack01_01_01.zip", pacchetto: "pack01", appversione: 1, revisione: 1, file: "pack01_02_01.zip", pacchetto: "pack01" , appversion: 2, revision: 1, file: "pack02_01_01.zip", pacchetto: "pack02", appversione: 1, revisione: 1]
Tieni presente che la tua app e i contenuti pubblicati in precedenza potrebbero evolvere nel tempo.
Fornire un flag di "revisione" per ogni pacchetto nel metodo elenco, questo sarà utile per rilasciare aggiornamenti, correggere bug nel contenuto e implementare funzionalità di aggiornamento automatico nelle app. Anche se attualmente non hai intenzione di implementare l'aggiornamento automatico, pensa in avanti e metti comunque il flag di revisione nell'elenco per uno sviluppo futuro.
Dovresti includere anche un flag "versione app" nell'elenco dei pacchetti. Se dovessi pubblicare una nuova versione principale della tua app che comporta cambiamenti improvvisi nel formato dei contenuti, questo ti consentirà di fornire contenuti per le app più nuove e più vecchie attraverso lo stesso servizio Web.
Durante lo sviluppo di app, reti e dispositivi basati sui servizi tolleranza d'errore dovrebbe anche essere preso in considerazione. Le connessioni dati mobili sono solitamente meno stabili di quelle cablate, le app possono essere disinstallate e reinstallate e i dispositivi possono essere persi, sostituiti con quelli più recenti o ripristinati in fabbrica. Agli utenti dovrebbe essere data la possibilità di ripristinare app e contenuti in modo semplice e gli sviluppatori di piattaforme offrono diverse soluzioni pronte all'uso su questi argomenti.
Ricordati di controlla sempre lo stato della rete prima di chiamare i servizi remoti o gestire con cura gli errori di I / O di rete e informare correttamente gli utenti quando l'attività desiderata non può essere eseguita a causa della mancanza di una connessione dati attiva. Se le tue app devono sempre "funzionare online", potresti voler installare un watchdog nelle app che monitora costantemente lo stato della rete e genera un evento ogni volta che si verifica un cambiamento. Si consiglia inoltre di informare gli utenti di eventuali costi aggiuntivi durante il trasferimento di grandi quantità di dati su reti 3G o di roaming anziché Wi-Fi.
Sui dispositivi Android, questa attività può essere eseguita tramite ConnectivityManager e tramite SCNetworkReachability su iOS (controllare anche l'app di esempio fornita).
Sia Android che iOS forniscono utili API per gestire il backup cloud remoto dei dati delle app degli utenti che dovresti tenere a mente. Controlla la documentazione dell'iCloud API per iOS e la documentazione del servizio di backup Android per Android. Insieme ai servizi di backup integrati, si ottengono anche buone funzionalità di sicurezza dei dati. Tuttavia, è necessario fare attenzione a non sovraccaricare i servizi di backup con backup ridondanti o non necessari.
È inoltre possibile implementare il backup dei dati remoti personalizzati nei servizi Web, ma ti consiglio caldamente di attenersi agli standard e alle API della piattaforma integrate. Di solito ti fanno risparmiare tempo e sono attivamente gestiti dagli ingegneri del software della piattaforma. È probabile che le patch del sistema operativo vengano prontamente installate al momento del rilascio.
Se fornisci contenuti a pagamento tramite fatturazione in-app nella tua app, consentendo agli utenti di recuperare i loro acquisti dopo la reinstallazione dell'app e il ripristino dei dispositivi obbligatorio. Fortunatamente, iOS e Android hanno API integrate per gestire anche questi scenari.
Quando le app abilitate per l'acquisto in-app vengono eseguite per la prima volta (o la prima volta dopo una reinstallazione), è necessario eseguire una procedura di controllo acquisto-ripristino. Sia iOS che Android forniscono una buona documentazione ufficiale su questo argomento.
Durante lo sviluppo per Android, ricorda che solo gli articoli "gestiti" possono essere ripristinati in un secondo momento e sono disponibili solo su un acquisto una tantum per utente. Ciò implica alcune considerazioni valide anche per lo sviluppo di iOS.
Supponiamo che tu stia sviluppando un gioco di ruolo e desideri consentire ai giocatori di acquistare oggetti come pozioni per la salute attraverso la fatturazione in-app. Innanzitutto, poiché gli utenti possono acquistare tutte le pozioni che desiderano, non possono essere "gestite", quindi le loro transazioni di acquisto non vengono archiviate in modo permanente. Inoltre, se un utente acquista 20 pozioni e ne usa 10, quindi disinstalla e reinstalla il gioco in un secondo momento, ripristinando gli acquisti tramite una semplice procedura standard, si inseriscono 20 pozioni nell'inventario dell'utente, 10 dei quali sono un regalo gratuito non voluto da gli sviluppatori.
Pertanto, potrebbe essere necessario implementare i propri servizi Web personalizzati e i metodi dell'app per gestire lo storage e il ripristino delle transazioni in scenari complessi o casi limite.
Le scadenze e i budget ti taglieranno spesso e non ti permetteranno di seguire tutte le migliori pratiche spiegate in questo articolo. Ma anche se sei costretto ad attenersi a un sottoinsieme più piccolo di funzionalità, pensa in avanti, passare un po 'di tempo in un buon design, e impacchetta i tuoi metodi e classi librerie che puoi riutilizzare ed estendere più tardi. Lascia gli stub quando senti che c'è spazio per ulteriori sviluppi. Prova anche a far rispettare retrocompatibilità quando estendi e migliora le tue librerie, in modo che anche le vecchie applicazioni possano essere riparate.
Questo è un esempio di stub:
public void sendData (Object data) if (validate (data)) client.send (dati); // Stub public boolean validate (Object data) // TODO - Validazione dei dati dell'attrezzo restituita true;
Se sei uno sviluppatore alle prime armi o non hai mai sviluppato applicazioni basate sui servizi, dovresti iniziare dall'applicazione di esempio fornita come un buon esercizio per migliorare le tue conoscenze e trasformarle in un'applicazione reale applicando tutti i concetti spiegati in questo articolo in un tempo. In alternativa, avviare una nuova applicazione da zero e integrarla con alcuni fornitori di servizi esistenti (Facebook, Twitter, Last.fm o Dropbox sarebbe un buon punto di partenza) seguendo lo stesso programma.
Se hai già sviluppato alcune applicazioni basate sul servizio e sulla rete, puoi rivedere il codice esistente e migliorarlo secondo i principi spiegati sopra, tenendo traccia di ogni miglioramento e impatto sulle prestazioni e la reattività.
Non dimenticare di controllare anche le risorse collegate, poiché ti porteranno più in profondità nel nucleo di ogni problema e di scaricare il server di esempio e le applicazioni client fornite con l'articolo.