Acest articol este o explorare a protocoalelor de servicii web, a formatelor comune de schimb de date și a celor mai bune practici. Dacă sunteți interesat să creați aplicații mobile performante care se conectează la web, citiți mai departe!
Selectarea unui protocol corespunzător și a unui format de schimb de date pentru a transmite date între aplicația dvs. mobilă și "net" este una dintre cele mai importante decizii pe care trebuie să le faceți în timpul procesului de dezvoltare. Protocoalele cele mai comune și utilizate pe scară largă sunt REST, XML-RPC și SOAP.
Toate aceste protocoale transportă date prin protocolul HTTP. Protocoalele XML-RPC și SOAP sunt bazate pe XML, în timp ce serviciile REST se pot baza pe diferite formate de date, cele două cele mai obișnuite fiind XML și JSON. În special, SOAP este apreciat și adoptat de aplicațiile întreprinderii, deoarece impune cu strictețe modelele de date și descrie interfețele publice prin WSDL, făcând astfel unele instrumente de dezvoltare (cum ar fi Microsoft Visual Studio for .NET) capabile să configureze automat obiecte și metode de consum serviciile doar prin adăugarea la proiect a unei referințe la serviciul WSDL.
XML, cu toate acestea, este mai puțin eficient decât JSON atunci când operează într-un scenariu de rețea limitat de bandă, cum ar fi dezvoltarea mobilă. Rețelele de date mobile (WWAN) sunt, de obicei, mai puțin fiabile decât rețelele prin cablu (LAN) sau wireless (WLAN), deoarece clienții în mișcare pot scădea cu ușurință zonele de acoperire și de acoperire. De asemenea, unii utilizatori nu se abonează la planurile de date "plane" și sunt efectiv taxați de traficul din rețea.
Deci, în timp ce dezvoltați pentru mobil, trebuie să alegeți întotdeauna simplitatea și reducerea traficului.
Să comparăm XML simplu cu JSON cu un exemplu de răspuns:
XML
Bună, dispozitiv!
JSON
returnValue: "Bună ziua, dispozitiv!"
După cum puteți vedea, JSON are un volum util mai mic deoarece trebuie doar să-i împachetezi datele cu paranteze (creion pentru obiecte, pătrate pentru matrice) și citate, în timp ce XML are nevoie de un nod rădăcină completă și de etichete de deschidere-închidere pentru fiecare element sau grup. Salvarea pe acele etichete poate reduce în mod semnificativ sarcina utilă a răspunsului și cu cât sunt mai multe date pe care le transferați, cu atât mai mare va fi încărcarea "padding" cu XML.
În plus, SOAP și XML-RPC necesită structuri de date XML mai complexe (cum ar fi "plicul" SOAP), adăugând o greutate suplimentară încărcăturii utile.
Din acest motiv, vă recomand să alegeți JSON pentru formatul de schimb de date al aplicației dvs. și ODIHNĂ pentru protocolul de transfer, cu excepția cazului în care sunt necesare în mod explicit pentru nevoile dvs. XML, SOAP sau XML-RPC. Dacă aveți nevoie să impuneți un model de date, puteți obține acest lucru și cu JSON, utilizând JSON Schema sau WSDL 2.0.
Pentru referințe și citiri suplimentare despre protocoalele discutate și formatele de date, consultați următoarele:
Deoarece majoritatea serviciilor web operează pe rețele publice, protejarea datelor care vor fi schimbate între servicii și aplicație este una dintre cele mai importante probleme pe care trebuie să le abordați. Multe servicii web oferă funcționalități de la distanță utilizatorilor autentificați, astfel încât datele personale de utilizator și acreditările de autentificare trebuie să fie transferate și prin rețea.
Datele personale, datele contului și datele de acreditare ar trebui să fie nu călătoriți în formă clară într-o rețea publică, deci aceasta înseamnă că serviciile Web și aplicațiile ar trebui să implementeze criptografia. Vestea bună este că cele mai comune protocoale de transport de date prin HTTP, astfel încât să vă puteți baza pe bine cunoscut, de încredere și robust Protocolul HTTP SSL / TLS (HTTPS) care se bucură de un suport pe scară largă atât pe partea de server, cât și pe partea clientului.
Activarea SSL pe serverele web obișnuite este destul de ușoară (există o mulțime de resurse utile pentru Apache, IIS și Nginx). Tot ce trebuie să faceți este să cumpărați un certificat SSL și să îl configurați pe serverul dvs. În a în cel mai rău caz, de asemenea, puteți să emiteți un certificat cu auto-semnare care să vă aducă criptare gratuită, dar aș face-o nu recomanda acest lucru. Unele CA difuzează certificate la prețuri reduse, iar beneficiile pe care le obțineți din lucrul cu un certificat de încredere sigură merită costul suplimentar (adică prevenirea atacurilor de tip "man-in-the-middle" prin utilizarea PKI). Utilizarea certificatelor auto-semnate ar putea necesita codare suplimentară sau chiar "hacks" specifice aplicațiilor, deoarece unele biblioteci de rețea vor refuza conexiunile HTTPS nesigure (consultați aceste articole despre Android, # 1 și # 2 și despre iOS).
Activarea SSL-ului pe partea clientului este o metodă fără limită: limbile de programare obișnuite au de obicei clase și biblioteci HTTP care oferă suport HTTP-SSL nativ și vor avea grijă automatizată de criptare doar prin utilizarea URL-urilor "https: //" : // "URL-uri pentru a consuma servicii web.
Dacă alegeți un certificat SSL la preț scăzut, asigurați-vă că dispozitivele și sistemele de operare pe care doriți să le dezvoltați au certificatul rădăcină CA al emitentului inclus în pachet, altfel nu vor avea încredere în certificat.
Niciodată nu ar trebui să cereți utilizatorilor să le patch-uri, să le modifice sau să-și spargă sistemele pentru a rula aplicațiile dvs. și dacă faceți acest lucru, nu vă așteptați ca mulți dintre ei să respecte.Tranzacțiile de servicii web sunt menite a fi atomic, interoperabilă și scalabil, astfel încât serviciile Web sunt de obicei apatrid (consultați această discuție interesantă despre semnificația conexiunilor "apatrid").
Multe servicii web oferă funcționalități legate de utilizator și acces la informații sensibile. Firește, acest lucru necesită autentificare. Deoarece astfel de tranzacții sunt apatrizi, în mod tradițional este necesar să semnați cereri cu o cheie specifică utilizatorului, furnizând autentificare cu fiecare apel de la distanță. Chiar și atunci când se transferă date prin HTTPS, acreditările utilizatorilor prezintă cel mai mare risc atunci când sunt transmise printr-o rețea publică. Criptarea este uneori întreruptă.
Această dilemă este în cazul în care autentificarea bazată pe token, cum ar fi OAuth, vine la îndemână. Utilizând autentificarea bazată pe token, trebuie să trimiteți acreditările utilizatorului doar o singură dată. Dacă utilizatorul este autentificat cu succes, acesta va primi token-uri care pot fi folosite pentru a autentifica apelurile ulterioare de la distanță.
Valabilitatea tokenului se întinde pe o durată limitată de viață și poate fi revocată oricând de către emitentul său (adică server). Cu autentificarea bazată pe token, puteți împărtăși aceleași acreditări pentru utilizatori între diferite aplicații și servicii fără ca serviciile / aplicațiile conectate să cunoască oricând acreditările reale ale utilizatorilor. Mai mult, această metodă de autentificare păstrează în siguranță un cache local al acreditărilor pe dispozitivul utilizatorului, astfel încât utilizatorul să poată fi "amintit" și nu va trebui să se autentifice de fiecare dată când va folosi aplicația (introducerea parolelor complexe pe handheld-uri poate fi un real durere și pot afecta grav recenzii despre aplicații).
OAuth este cel mai obișnuit cadru de autentificare pe bază de jetoane și a fost adoptat de marii jucători precum Google, Twitter, Facebook și așa mai departe. Permițând utilizatorilor să reutilizeze conturile existente, sărind peste formularele de înregistrare enervante și păstrând controlul asupra accesului la datele lor personale, puteți crește semnificativ baza de utilizatori.
Unii furnizori de servicii OAuth au nevoie de propriul SDK pentru a fi importate în aplicațiile dvs. pentru a activa autentificarea, în caz contrar există o mulțime de biblioteci OAuth gata făcute în jurul cărora puteți să vă conectați la aplicație. Există, de asemenea, cadre precum oauth-php disponibile pentru a construi furnizori OAuth personalizați.
Aș sugera semnalizarea ca o bibliotecă de clienți Android OAuth și oauthconsumer pentru iOS.
Toate aceste biblioteci vin cu exemple utile și sunt ușor de implementat. Cu toate acestea, construirea surselor de semnalizare pe mașină sau importarea acestora în aplicația dvs. poate fi un pic de durere, însă, de fapt, nu trebuie să treceți prin acest proces. În schimb, puteți importa binarele JAR în proiectul dvs. și ar trebui să fiți setați. În iOS, aceasta ar fi similară importării unei biblioteci statice (*. Un fișier) în proiectul dvs..
Metoda cea mai comună de autentificare pentru serviciile bazate pe SOAP este o extensie SOAP numită autentificare de bază HTTP (uneori denumită Digest Authentication). Aceasta este o procedură standard, bine susținută, integrată în toate serverele web cele mai uzuale, cum ar fi Apache, Nginx și IIS. Se bazează pe o pereche de nume de utilizator și parolă care trebuie trimisă pe server prin intermediul antetelor HTTP.
În mod normal, nu va trebui să implementați manual aplicațiile de bază în aplicațiile dvs., deoarece este acceptat pe scară largă în cele mai comune limbi de programare. Cadrul .NET se bazează pe clasa NetworkCredential pentru a furniza acreditările de bază și digest auth la cererile HTTP, PHP îl acceptă prin cURL și Java prin Authenticator.
În cazul în care trebuie să implementați Auth Basic, trebuie doar să adăugați acest antet la solicitările dvs.:
Nume de utilizator de bază: parola
Valorile "nume de utilizator" și "parolă" trebuie să fie valabile base64-encoded.
Vă rugăm să observați asta HTTP Basic Auth este cel mai bine utilizat în combinație cu protocolul HTTPS, deoarece transferă acreditările în text simplu formă. Digest Auth este un pic mai sigur, deoarece are de fapt o valoare a parolei, dar HTTPS este recomandat oricum pentru a evita atacurile brute force hash.
Mai multe detalii și specificații privind acest subiect pot fi găsite în memoria IETF RFC 2617.
Atunci când alegeți o metodă de autentificare sau integrați servicii cunoscute (cum ar fi rețelele sociale), ar trebui să țineți cont și de bibliotecile native care sunt construite în multe platforme avansate, cum ar fi iOS și Android. Acest lucru vă poate economisi mult timp și multe linii de cod.
Android oferă un cadru frumos pentru a centraliza gestionarea contului de utilizator, clasa AccountManager. Ghidul oficial al dezvoltatorului Android vă oferă o bună documentație pentru această clasă, împreună cu câteva sfaturi pentru a integra OAuth 2 sau pentru a scrie propriul dvs. "Tip de cont personalizat".
Cu iOS 6, Apple a introdus un nou cadru social pentru integrarea unor servicii importante precum Twitter, Facebook și Sina Weibo la un nivel de sistem de operare. Chiar dacă nu aveți nevoie să integrați aceste servicii în aplicația dvs., puteți găsi o modalitate adecvată de a profita de metodele de autentificare încorporate prin personalizare.
Atunci când dezvoltați pentru aplicații mobile, este important să păstrați volumul de date cât mai scăzut posibil. Această secțiune va discuta mai multe strategii pentru a face acest lucru.
Compresie ZIP poate reduce în mod semnificativ textul și, de asemenea, greutatea datelor binare și este bine susținută pe majoritatea platformelor, deci utilizați-o bine dacă aveți nevoie să transferați date importante pe rețelele mobile. Bibliotecile utile pentru gestionarea fișierelor ZIP sunt disponibile pentru Android (adică decomprimare) și iOS (adică Ziparchive).
Dacă aveți nevoie să redirecționați conținut audio / video către aplicațiile dvs. mobile, alegeți platforme avansate de streaming care le permit să scaneze fluxurile în funcție de performanța rețelei / dispozitivului, cum ar fi protocolul HTTP Live Streaming (HLS) al Apple. În caz contrar, favorizarea reacției față de calitatea media este de obicei o alegere bună. Redați-vă cu compresoare și setări audio și video diferite, optimizând cât de mult puteți. De asemenea, puteți grupa dispozitivele în funcție de natură (handheld-uri cu ecran mic, dispozitive portabile cu ecran lat și tablete) și oferă conținut diferit pentru fiecare tip.
Multe dispozitive mobile au afișaje HD, dar conținutul HD pe ecrane mici merită cu adevărat în plus față de lățimea de bandă suplimentară? Fiți cinstit cu privire la relevanța calității media în aplicațiile dvs. și încercați să găsiți cel mai bun echilibru între calitate și greutate.
Să presupunem că trebuie să codificați o aplicație pentru cititor pentru un ziar online. Mai întâi, ar trebui să permiteți utilizatorilor dvs. să funcționeze offline ori de câte ori este posibil. În timp ce unele aplicații necesită întotdeauna o rețea activă (adică servicii de mesagerie), mulți alți utilizatori ar trebui să utilizeze numai rețeaua descărcați pachetele de date și cache-le pe dispozitiv.
Acest lucru va îmbunătăți performanța aplicațiilor, va salva banii utilizatorilor pe planurile de date mobile și nu va face aplicația utilizabilă atunci când rețeaua nu este disponibilă (de exemplu în timpul zborului).
Când descărcați conținut pe dispozitivele care stochează dispozitive de stocare externe (de exemplu, carduri de memorie), ar trebui să permiteți utilizatorilor să aleagă unde să stocheze conținutul descărcat (adică stocarea internă sau externă) sau pur și simplu preferă stocarea externă oricum. Dispozitivele de nivel de intrare, de obicei, prezintă o stocare internă destul de mică și pot deveni instabile sau lente când spațiul de stocare intern este plin. Dacă aplicațiile dvs. ocupă o mulțime de spațiu de stocare, este posibil ca acestea să fie dezinstalate pentru a economisi spațiu.
Să revenim la exemplul aplicației cititorului. Fiecare articol este o singură piesă și, deși articolele ar putea fi legate între ele, nu există niciun motiv pentru care nu ar trebui să permiteți utilizatorilor să înceapă să citească articole chiar și în timp ce încă se mai descarcă conținut suplimentar. Deci, împachetați fișierele fiecărui articol (text, imagini, atașamente și materiale media) în arhive ZIP separate și să furnizeze o metodă de serviciu web pentru ca aplicația să poată prelua lista articolelor disponibile. Cereți aplicației să descarce pachete ZIP unul câte unul apoi le puneți la dispoziție în aplicație de îndată ce fiecare dintre ele a fost descărcat și în timp ce altele sunt descărcate în fundal. Aceasta este o performanță excelentă și o îmbunătățire a experienței utilizatorului în comparație cu așteptarea până când întregul încărcătură utilă a fost descărcată! De asemenea, ați putea permite utilizatorilor să aleagă pachetele pe care doresc să le descarce sau nu (permițându-le să economisească spațiu, timp și trafic) și să le permită să elimine pachete unice pentru a economisi spațiu de stocare fără a elimina întreaga aplicație.
Următorul este un răspuns de la aplicația serverului demo inclus în acest articol:
pachet: "pack01_01_01.zip", pachet: "pack01", aplicație: 1, revizie: 1, fișier: "pack01_02_01.zip", pachet: , appversion: 2, revizuire: 1, fișier: "pack02_01_01.zip", pachet: "pack02", appversion: 1, revision: 1]
Rețineți că aplicația dvs. și conținutul anterior lansat pot evolua în timp.
Furnizați un flag "revizie" pentru fiecare pachet din metoda listei, aceasta va fi utilă pentru a lansa actualizări, pentru a repara erorile în conținut și pentru a implementa funcționalitatea automată a actualizărilor în aplicațiile dvs. Chiar dacă nu intenționați în prezent să implementați actualizarea automată, gândiți-vă și puneți pavilionul de revizuire în lista dvs. oricum pentru o dezvoltare viitoare.
Ar trebui să includeți, de asemenea, un steag "app-version" în lista de pachete. Dacă lansați o nouă versiune majoră a aplicației dvs. care duce la ruperea modificărilor în formatul conținutului, acest lucru vă va permite să furnizați conținut atât pentru aplicațiile mai noi, cât și pentru cele mai vechi prin intermediul aceluiași serviciu Web.
În timp ce dezvoltăm aplicații, rețea și dispozitive bazate pe servicii toleranță la defecte ar trebui, de asemenea, luate în considerare. Conexiunile mobile de date sunt de obicei mai puțin stabile decât cele cablate, aplicațiile pot fi dezinstalate și reinstalate, iar dispozitivele pot fi pierdute, înlocuite cu altele noi sau restaurate din fabrică. Utilizatorilor ar trebui să li se ofere posibilitatea de a restabili aplicațiile și conținutul într-un mod facil și dezvoltatorii de platforme oferă câteva soluții utile pentru aceste probleme.
A își aminti să verificați întotdeauna starea rețelei înainte de a apela servicii la distanță sau de a gestiona cu atenție erorile de rețea I / O și de a informa în mod corespunzător utilizatorii dvs. atunci când sarcina dorită nu poate fi realizată din cauza lipsei unei conexiuni de date active. În cazul în care aplicațiile dvs. trebuie să funcționeze întotdeauna "online", este posibil să doriți să setați un watchdog în aplicațiile dvs. care monitorizează constant starea rețelei și declanșează un eveniment ori de câte ori apare o schimbare. De asemenea, este posibil să doriți să informați utilizatorii cu privire la posibilele costuri suplimentare atunci când transferați cantități mari de date pe rețelele 3G sau roaming decât pe Wi-Fi.
Pe dispozitive Android, această sarcină poate fi realizată prin intermediul ConnectivityManager și prin intermediul SCNetworkReachability pe iOS (verificați și aplicația probată furnizată).
Atât dispozitivele Android cât și iOS oferă API-uri utile pentru a gestiona backupul cloud-ului de la distanță pentru datele aplicațiilor de utilizator pe care ar trebui să le țineți cont. Consultați documentația API iCloud pentru iOS și documentația Serviciului de copiere de rezervă Android pentru Android. Împreună cu serviciile de backup încorporate, beneficiați, de asemenea, de caracteristici bune de securitate a datelor. Cu toate acestea, trebuie să aveți grijă să nu supraîncărcați serviciile de rezervă cu copii de rezervă redundante sau inutile.
De asemenea, ați putea implementa backup de date la distanță personalizat în serviciile dvs. Web, dar vă recomandăm cu insistență să respectați standardele și API-urile de platformă integrate. De obicei, acestea vă vor economisi timp și sunt întreținute activ de către inginerii software de platformă. OS patch-uri sunt, de asemenea, mult mai probabil să fie instalate prompt atunci când eliberat.
Dacă furnizați conținut plătit prin facturare în aplicație în aplicația dvs., permițându-i utilizatorilor recuperează achizițiile după reinstalarea aplicației și recuperarea dispozitivului obligatoriu. Din fericire, iOS și Android au built-in API-uri pentru a face față și acestor scenarii.
Când aplicațiile activate pentru achiziționarea în aplicații rulează pentru prima dată (sau prima dată după o reinstalare), trebuie să executați o procedură de verificare a restaurării achiziției. Atât iOS, cât și Android oferă o documentație oficială frumoasă cu privire la această problemă.
La dezvoltarea pentru Android, amintiți-vă că numai articolele "reușite" pot fi restaurate ulterior și sunt disponibile numai pentru o achiziție unică pentru fiecare utilizare. Acest lucru implică unele considerente care se aplică și dezvoltării iOS.
Să presupunem că veți dezvolta un joc de rol și doriți să permiteți jucătorilor să cumpere elemente precum poțiuni de sănătate prin facturarea în aplicație. În primul rând, deoarece utilizatorii pot cumpăra cât de multe poțiuni doriți, ele nu pot fi "gestionate", astfel încât tranzacțiile lor de cumpărare nu sunt stocate permanent. De asemenea, dacă un utilizator cumpără 20 de poțiuni și folosește 10, apoi dezinstalează și reinstalează jocul mai târziu, restabilirea achizițiilor printr-o procedură standard simplă ar pune 20 de poțiuni înapoi în inventarul utilizatorului, dintre care 10 reprezintă un cadou gratuit neintenționat de la dezvoltatorii.
Deci, este posibil să aveți nevoie să implementați propriile servicii Web personalizate și metode de aplicații pentru a gestiona stocarea și recuperarea tranzacțiilor în scenarii complexe sau cazuri de margine.
Termenele limită și bugetele vă vor tăia de multe ori și nu vă vor lăsa să urmați cele mai bune practici explicate în acest articol. Dar chiar dacă sunteți forțat să rămâneți la un subset mai mic de caracteristici, gândiți-vă înainte, petrece ceva timp în design bun, și împachetați metodele și clasele tale biblioteci pe care le puteți reutiliza și extinde mai târziu. Lăsați stubs atunci când simțiți că există loc de dezvoltare. De asemenea, încercați să aplicați compatibilitate înapoi atunci când vă extindeți și îmbunătățiți bibliotecile, astfel încât aplicațiile mai vechi pot fi și patch-uri.
Acesta este un exemplu de stub:
public void sendData (date obiect) if (validate (data)) client.send (date); // Stub public boolean validate (Object data) // TODO - Implementarea validării datelor return true;
Dacă sunteți un dezvoltator novice sau nu ați dezvoltat niciodată aplicații bazate pe servicii, ar trebui să începeți din aplicația probată furnizată ca un exercițiu bun pentru a vă îmbunătăți cunoștințele și pentru ao transforma într-o aplicație în lumea reală, aplicând toate conceptele explicate în acest articol, timp. Alternativ, începeți o nouă aplicație de la zero și integrați-o cu un furnizor de servicii existent (Facebook, Twitter, Last.fm sau Dropbox ar fi un bun punct de pornire) urmând același program.
Dacă ați dezvoltat deja unele aplicații bazate pe servicii și în rețea, puteți revizui codul existent și le puteți îmbunătăți în conformitate cu principiile explicate mai sus, urmărind fiecare îmbunătățire și impact asupra performanței și a capacității de reacție.
Nu uitați să verificați și resursele asociate, deoarece acestea vă vor duce mai adânc în centrul fiecărei probleme și veți descărca aplicațiile de tip server și aplicații client furnizate împreună cu articolul.