Finalizare Batîr P Ion 4c [618130]
UNIVERSITATEA DIN ORADEA FACULTATEA DE INGINERIE ELECTRICĂ ȘI TEHNOLOGIA INFORMAȚIEI PROGRAMUL DE STUDIU CALCULATOARE FORMA DE ÎNVĂȚĂMÂNT IF Proiect de diplomă COORDONATOR ȘTIINȚIFIC PROF. UNIV. DR. ING. GYŐRÖDI ROBERT ABSOLVENT: [anonimizat] 2020
UNIVERSITATEA DIN ORADEA FACULTATEA DE INGINERIE ELECTRICĂ ȘI TEHNOLOGIA INFORMAȚIEI PROGRAMUL DE STUDIU CALCULATOARE FORMA DE ÎNVĂȚĂMÂNT IF Dezvoltarea unei aplicații mobile pentru minimizarea risipei alimentare COORDONATOR ȘTIINȚIFIC PROF. UNIV. DR. ING. GYŐRÖDI ROBERT ABSOLVENT: [anonimizat] 2020
UNIVERSITATEA DIN ORADEA FACULTATEA de Inginerie Electrică și Tehnologia Informației DEPARTAMENTUL CALCULATOARE ȘI TEHNOLOGIA INFORMAȚIEI TEMA_________ Proiectul de Finalizare a studiilor a student: [anonimizat] 1). Tema proiectului de finalizare a studiilor: Dezvoltarea unei aplicații mobile pentru minimizarea risipei alimentare 2). Termenul pentru predarea proiectului: septembrie 2020 3). Elemente inițiale pentru elaborarea proiectului de finalizare a studiilor – 4). Conținutul proiectului de finalizare a studiilor: introducere, noțiuni introductive, tehnologii utilizate, dezvoltarea aplicației, concluzii, bibliografie. 5). Material grafic: – 6). Locul de documentare pentru elaborarea proiectului: Internet, Cărți 7). Data emiterii temei: mai 2020 Coordonator științific Prof. univ. dr. ing. GYŐRÖDI Robert
Cuprins INTRODUCERE …………………………………………………………………………………………………….. 5 1.1. Contextul proiectului ……………………………………………………………………………………………… 5 1.2. Ideea și scopul proiectului ……………………………………………………………………………………….. 5 1.3. Structura proiectului ………………………………………………………………………………………………. 6 NOȚIUNI INTRODUCTIVE ………………………………………………………………………………………. 7 2.1. Definiții generale despre aplicațiile mobile ………………………………………………………………… 7 2.2. Istoria și evoluția dezvoltării aplicațiilor mobile ………………………………………………………….. 9 2.3. Prezentarea generală a metodelor de dezvoltare a aplicațiilor mobile ………………………….. 10 2.4. Analiza comparativă a tehnologiilor pentru dezvoltarea aplicațiilor cross-platform …………. 13 TEHNOLOGII UTILIZATE ……………………………………………………………………………………….. 17 3.3. JavaScript ……………………………………………………………………………………………………………. 17 3.2. React …………………………………………………………………………………………………………………. 18 3.3. React Native ……………………………………………………………………………………………………….. 21 3.4. Flexbox ………………………………………………………………………………………………………………. 23 3.5. Firebase ……………………………………………………………………………………………………………… 24 3.6. Firebase Firestore ………………………………………………………………………………………………… 25 3.7 Firebase Authentication …………………………………………………………………………………………. 26 3.8 Firebase Cloud Functions ……………………………………………………………………………………….. 27 DEZVOLTAREA APLICAȚIEI ……………………………………………………………………………………. 28 4.1. Setarea mediului de dezvoltare a aplicației mobile ……………………………………………………. 28 4.2. Implementarea stivei de autentificare …………………………………………………………………….. 31 4.3. Implementarea ecranelor aplicației …………………………………………………………………………. 36 CONCLUZII ………………………………………………………………………………………………………… 44 BIBLIOGRAFIE ……………………………………………………………………………………………………. 45
5 INTRODUCERE 1.1. Contextul proiectului În prezent, omul contemporan încearcă să obțină un nivel cât mai ridicat de confort în toate sferele vieții. În condițiile moderne este greu de imaginat viața fără un telefon mobil, tabletă sau oricare alt dispozitiv multimedia. Dispozitivele mobile joacă un rol foarte important în viața omului. Aceste dispozitive mereu sunt la îndemâna noastră, sunt accesibile și comode în utilizare, și ele nu sunt doar un mijloc de comunicare, dar dispun și de o varietate mare de funcții și aplicații utile, cum ar fi: calculatorul, organizatorul, convertorul, calendarul, ceasul. Odată ce dispozitivele mobile au început să fie disponibile publicului larg pentru acestea s-au dezvoltat o mulțime de soluții software care îndeplinesc o gamă largă de sarcini. Eficiența și funcționalitatea lor sunt aduse la un nivel atât de înalt datorită aplicațiilor care au fost dezvoltate pentru rezolvarea unor probleme concrete. 1.2. Ideea și scopul proiectului În zilele de astăzi una din cele mai grave probleme ecologice este problema risipei alimentare. Deseori cumpărăm sau pregătim produse alimentare care în final ajung la coșul de gunoi. După datele statistice, în UE sunt irosite anual peste 20% din totalul de alimente produse ceea ce se rezumă la o pierdere financiară de peste 143 miliarde de euro[1]. Problema risipei alimentare nu se rezumă doar la pagube financiare, ci și la influențe negative asupra sferelor sociale, economice și de mediul înconjurător. Astfel, se pierde o cantitate enormă de apă, energie, pământ și muncă umană folosită pentru producerea alimentelor care în final ajung la groapa de gunoi și nu sunt consumate niciodată. O mare parte din emisia gazelor de seră se datorează domeniului alimentar, astfel, încât pentru creșterea culturilor, se folosesc o mulțime de fertilizatori și carburanți în producție și transport. În majoritatea cazurilor de risipă alimentară problema se află la sfârșitul lanțului de aprovizionare, în consumatorul final. Din aceste considerente s-a decis dezvoltarea unei aplicații mobile care să contribuie la minimizarea risipei alimentare, ajutând utilizatorul aplicației să ducă contul produselor procurate și pregătite.
6 În prezent, indiferent de locație, de regulă, dispozitivul mobil este întotdeauna la îndemână, astfel se asigură faptul că utilizatorul poate mereu interacționa cu aplicația mobilă și viceversa. Acesta are posibilitatea de a nota alimentele procurate când se află la magazin sau le poate nota după ce le pregătește în aplicație. Împreună cu numele produsului se cere notarea și a datei de expirare pentru fiecare produs în parte. După introducerea datelor utilizatorul aplicației are disponibil listarea tuturor produselor sale în ordinea în care expira fiind la curent la care produse se atragă atenția mai mult. Utilizatorul este notificat cu o perioadă de timp înainte despre faptul că alimentele sale urmează să expire într-un timp apropiat, astfel motivându-l să le consume sau să pregătească ceva din ele. Astfel se asigură o soluție împotriva risipei alimentare la nivel de consumator. Aplicația mobilă mai vine în ajutorul utilizatorului prin faptul că aceasta oferă recomandări de rețete care ar putea fi pregătite luând în calcul alimentele pe care persoana care folosește aplicația le are disponibile. 1.3. Structura proiectului Proiectul de față urmărește scopul de a descrie fundamentele teoretice, tehnologiile și conceptele utilizate, procesul de proiectare și implementare a unei aplicații mobile menite să combată efectul risipei alimentare. Lucrarea este structurată în 5 capitole. Primul capitol reprezintă introducerea în care se vorbește despre contextul și motivația scrieirii proiectului de față. Capitolul doi este despre conceptele de bază teoretice despre dezvoltarea aplicațiilor mobile, acest capitol oferă o largă înțelegere despre soluțiile care sunt oferite la momentul de față în domeniu, diferențele, avantajele și dezavantajele fiecărei tehnologii în parte. Capitolul trei cuprinde descrierea tehnologiilor folosite pentru implementarea aplicației. Capitolul patru descrie procesul de proiectare a aplicației, structura și funcționalitatea ei. Capitolul cinci finalizează proiectul prin descrierea concluziilor făcute. Consider că aplicația dezvoltată reprezintă o soluție comodă, accesibilă și ușor de utilizat pentru combaterea efectelor de risipă alimentară.
7 NOȚIUNI INTRODUCTIVE 2.1. Definiții generale despre aplicațiile mobile Oriunde am fi, oriunde am merge, oamenii utilizează peste tot dispozitivele mobile pentru a comunica cu familia și prietenii, pentru a fotografia și a posta pozele pe rețelele de socializare, pentru a căuta poziția de localizare a celui mai apropiat restaurant sau a vizualiza titlurile de știri. Dispozitivele mobile au o mulțime de forme și stiluri. Acestea funcționează pe diferite sisteme de operare, cele mai populare fiind iOS de la Apple și Android de la Google. Unele au ecrane mari, altele au tastaturi fizice și funcționează în rețelele 3G, 4G sau WiFi. Telefoanele mobile pot avea, de asemenea, senzori de accelerație, senzori de localizare și chiar modalități pentru plăți. Unele dintre aceste dispozitive mobile nici nu sunt telefoane, acestea sunt tabele cu ecrane mai mari și conexiune la rețea doar pentru schimb de date. În ciuda tuturor diferențelor, dispozitivele mobile sunt similare între ele prin faptul că toate rulează aplicații mobile. Aplicațiile mobile pot fi împărțite în mai multe tipuri: • Aplicații native. Aplicațiile native de pe telefon reprezintă programare executabile binare care au fost create folosind un kit de dezvoltare software, numit SDK (Software Development Kit). SDK-urile există pentru fiecare sistem de operare mobil. De exemplu, pentru a crea o aplicație pentru sistemul de operare iOS, este nevoie de SDK-ul iOS și limbajul de programare Objective-C. Aplicațiile pentru Android se dezvoltă cu ajutorul SDK-ului Android și se scriu în Java. Astfel, se primește că pentru scrierea unei aplicații pe dispozitivele mobile este nevoie de a cunoaște SDK-ul fiecărui sistem de operare mobil, împreună cu limbajele de programare respective. Evident că studierea SDK-ului și a limbajului de programare ia timp, respectiv dezvoltarea aplicației mobile devine o provocare. Aplicațiile mobile, de obicei, sunt distribuite prin magazinele de aplicații. De exemplu, pentru sistemul de operare iOS există magazinul App Store, iar pentru Android aplicațiile se pot instala din magazinul Google Play.
8 • Aplicațiile Web Aplicațiile Web se încarcă în navigatorul (browser-ul) din telefonul mobil. Acestea diferă de aplicațiile native prin faptul că codul acestor aplicații este scris folosind tehnologii web cum ar fi HTML, CSS și JavaScript. Ele funcționează la fel indiferent de sistemul de operare al telefonului. Prin urmare, nu este nevoie de studierea limbajelor de programare și SDK pentru fiecare dispozitiv în parte. HTML și JavaScript sunt familiare dezvoltatorilor web, cu ajutorul acestora se creează pagini web pentru navigatoarele desktop. În majoritatea cazurilor browser-ele mobile pot reda paginilor web, dar de obicei se folosesc versiuni mobile a acestor site-uri cu mai puține informații (datorită dimensiunii mai mici e cranului). Aplicațiile web nu sunt distribuite prin magazinul de aplicații, ele sunt reprezentate de adrese URL care pot fi incluse în alte pagini web, în e-mail-uri sau chiar notate pe hârtie. Aplicațiile native și web au avantajele și dezavantajele lor, fiind cauza a multor discuții despre care sunt mai bune. În multe cazuri această dispută poate fi soluționată prin aplicațiile hibride care încearcă să combine avantajele ambelor tipuri de aplicații mobile. • Aplicațiile hibride Aplicațiile hibride, ca și aplicațiile web, sunt create cu ajutorul tehnologiilor web, dar sunt ambalate în aplicații native. O aplicație hibridă poate fi scrisă pentru mai multe sisteme de operare folosind limbajele de programare familiare pentru dezvoltatorii web. O dată ce aplicația este, de fapt, încorporată într-o aplicație nativă aceasta are acces la funcțiile dispozitivului cum ar fi camera, localizarea, agenda de telefon, notificări etc. Aplicațiile hibride pot fi distribuite și instalate prin magazinele de aplicații, cum sunt cele native. Totuși aplicațiile hibride reprezintă în esență o aplicație web, doar asamblate într-un mediu nativ. Astfel, de obicei acestea nu reprezintă o performanță bună când vine vorba despre construirea unor elemente mai complexe. O soluție mai performantă și mai nou reprezintă aplicațiile cross-platform care folosesc direct componentele native. • Aplicațiile cross-platform Aplicațiile cross-platform reprezintă o nouă metodă de a dezvolta aplicații care ar funcționa la fel pe mai multe platforme folosind același cod. Acestea se asemănă foarte mult
9 cu aplicațiile hibride, diferența lor fiind faptul că folosesc module native. Aplicațiile cross-platform se construiesc cu ajutorul unui framework (seturi de funcții și librării pe baza unui limbaj de programare). Framework-ul comunică cu platforma nativă folosind SDK-ul acesteia. Aplicații cross-platform se pot integra foarte ușor și cu codul nativ. 2.2. Istoria și evoluția dezvoltării aplicațiilor mobile Aplicațiile și dispozitivele mobile au parcurs un drum lung al evoluției până când au ajuns la forma și funcționalitatea pe care o cunoaștem astăzi. Una din primele tehnologii care a permis rularea aplicațiilor terțe în telefonul mobil a fost WAP (Wireless Application Protocol) care a apărut în anul 1999[2]. Anume această tehnologie a conectat telefonul mobil cu internetul. Ea permitea cu ajutorul browser-ului din telefonul mobil conectarea și primirea datelor de la serverele din rețeaua internet. WAP a oferit oamenilor posibilitatea de a citit știri de pe telefonul mobil, de a folosi poșta electronică, de a descărca hărți și chiar posibilitatea de a rezerva bilete. Pentru aceasta, site-urile construite cu WAP foloseau un limbaj de marcaj special pentru ecranele mobile. Acesta era format din pagini simple care conțineau text și adrese de internet, aproape fără imagini. În anul 2001 pentru telefoanele Nokia a fost lansat sistemul de operare mobil Symbian[3]. Acesta fost unul dintre primele sisteme de operare mobile care a fost deschis pentru dezvoltarea aplicațiilor mobile de către părțile terțe. Symbian a prezentat o revoluție, dar tehnologia nu s-a bucurat de succes din cauza complexității prea mari de dezvoltare a aplicațiilor mobile sub acest sistem de operare și a capacităților limitate a telefoanelor de atunci. Dezvoltatorii aveau disponibil un set de instrumente slab dezvoltat pentru crearea aplicațiilor. Platforma se baza pe limbajul de programare C++ care era dificil de învățat și greu de compilat. Erau nevoie de prea multe forțe și resurse pentru a putea scrie o aplicație Symbian compatibilă pe toate telefoanele. De asemenea, majoritatea au fost descurajați de necesitatea de a achiziționa certificate de securitate pentru semnarea aplicațiilor. Fără prezența certificatului aplicație nu pornea deloc sau suferea foarte mult din punct de vedere a funcționalității. Cu toate acestea nici cei de la Nokia nu ofereau atenție în de ajuns sistemului său de operare mobil. Abia în 2009 s-au întreprins unele încercări de a salva situația, astfel încât s-a făcut oferit mai multe posibilități de dezvoltare a aplicațiilor prin framework-ul Qt și codul sursă Symbian a fost deschis[4]. Toate acestea trebuiau să ducă la popularizarea acestui sistem de operare și să salveze situația creată, dar în final Symbian nu a mai putut concura cu sistemele de operare iOS și Android.
10 În 2007 Steve Jobs a prezentat lumii întregi noul iPhone[5]. Noul telefon rula sistemul de operare iOS. Arhitectura acestui sistem de operare era complet închisă, Jobs nu dorea ca noul iPhone să conțină aplicații de la părți terțe. În schimb, el dorea ca dezvoltatorii să creeze aplicații web care puteau fi accesate prin marcaje de pe ecranul de pornire. Astfel cu browser-ul integrat pentru iOS – Safari se putea crea aplicații Web 2.0 care ar arăta bine și ar avea acces la toate interfețele telefonului: cameră, geo localizare, contacte etc. Dar această abordarea nu s-a bucurat de succes. Astfel, în 2008 Apple a deschis SDK-ul pentru iPhone tuturor doritorilor și în același timp prezentând și magazinul de aplicații App Store care a dat un impuls pentru industria dezvoltării aplicațiilor mobile [6]. În 2008 apare Android Market[7], iar în 2010 – Windows Phone Marketplace[8]. Aceasta a fost o nouă etapă în dezvoltarea aplicațiilor pentru dispozitivele mobile, deoarece de la divertisment (jocurile mobile) dezvoltatorii s-au accentuat pe rezolvarea problemelor reale. Dezvoltarea rapidă și paralelă a iOS și Android a creat o nouă problema. Un sistem bipolar pentru dezvoltatori, în care aceștia trebuia să suporte ambele platforme în același timp. Dezvoltarea unei aplicații simple pentru diferite platforme consuma o mulțime de resurse umane, de timp și financiare. În ajutor au venit framework-urile pentru crearea aplicațiilor pentru Android și iOS bazate pe tehnologiile de browser fără a folosi limbajele de programare native. 2.3. Prezentarea generală a metodelor de dezvoltare a aplicațiilor mobile Domeniul dezvoltării aplicațiilor mobile cuprinde în mare parte două tehnici disponibile: dezvoltarea nativă și dezvoltarea cross-platform. Prin dezvoltarea nativă se înțelege utilizarea limbajelor de programare originale și a instrumentelor de dezvoltare a sistemului de operare mobil. Pentru sistemul de operare iOS, aplicațiile sunt create în mediul de dezvoltare Xcode folosind următoarele limbaje de programare: Objective-C, Swift. Pentru crearea aplicațiilor pentru sistemul de operare Android se folosește mediul Android Studio și limbajul de programare Java și, mai nou, Kotlin. Fiecare mediu de dezvoltare conține un set întreg de utilități necesare pentru scrierea codului, proiectarea interfeței de utilizator, depanare, profilare (monitorizare) și dezvoltarea aplicațiilor. Mediul și setul de instrumente corespunzător sunt create special pentru fiecare sistem de operare mobil împarte și reprezintă cele mai comode și convenabile soluții de dezvoltare software.
11 Dezvoltarea aplicațiilor cross-platform înseamnă utilizarea unor utilități speciale numite framework pentru crearea aplicațialor care să funcțiune la fel pe mai multe platforme folosind același cod. Toată structura și logica aplicației sunt create folosind astfel de instrumente ca (React Native, Xamarin, Cordova etc.). În continuare voi analiza avantajele dezvoltării aplicațiilor native și a aplicațiilor cross-platform. Abordarea de dezvoltare cross-platform are următoarele avantaje: 1. Sunt necesare mai puține resurse pentru implementarea aplicației pe mai multe platforme. Acestea este, de fapt, esența dezvoltării aplicațiilor cross-platform. Același cod funcționează atât pe iOS, cât și pe Android. În acest mod pentru dezvoltarea proiectului este nevoie de mai puțin cod și, respectiv, de mai puțin programatori. Toate aceste momente reduc numărul de ore de lucru și bugetul proiectului. 2. Timpul mai mic de dezvoltare. Această se datorează faptului că sunt mai puține elemente specifice platformei și tehnologiile sunt mult mai simple, astfel timpul necesar dezvoltării aplicației e mai mic. 3. Ciclul de actualizare a aplicației e mai simplificat. În cazul în care este nevoie de actualizarea/adăugarea a unei noi funcționalități sau remedierea unei probleme acesta se face concomitent pentru toate platformele acoperite de proiect. 4. Posibilitatea de a utiliza versiunea web a proiectului. Cele mai multe soluții cross-platform folosesc familia de limbaje JavaScript. Astfel, dacă există deja o versiunea web a proiectului, atunci o parte semnificativă a codului și a componentelor se poate reutiliza fără modificări. 5. Folosirea aceleași logici. Logica încorporată în aplicație va funcția garantat la fel pentru toată lumea, indiferent de platformă. Logica scrisă și depanată o dată conține mai puțin greșeli și discrepanțe. Nu e nevoie de o muncă dublă sau triplă pentru găsirea problemelor și depanarea lor. Dezvoltarea în tehnologii și limbaje native pentru iOS și Android are următoarele avantaje: 1. Viteza de funcționare a aplicației. Din motivul că aplicația este creată utilizând instrumentele de dezvoltare originale (Xcode, Android Studio) codul compilat este optim pentru platforma sa specifică. Aplicația primește suport hardware complet (procesarea imaginilor cu ajutorul GPU, utilizarea multi-threading pentru calculul sarcinilor complexe, încărcarea conținutului în fundal). În timpul dezvoltării
12 programatorii pot măsura viteza tuturor secțiunilor de cod, și când e nevoie să le optimizeze, au la dispoziție instrumente de măsurarea a utilizării procesorului, memoriei interne, căutarea scurgerilor etc. 2. Flexibilitatea în implementare. Spre deosebire de constrângerile în timpul construcției interfețelor și a elementelor vizuale complexe date de framework-urile cross-platform, dezvoltarea nativă permite realizarea a tot ce permite platforma de dezvoltare. 3. Utilizarea ultimelor tehnologii și independența față de framework-ul cross-platform. Facilitățile și funcționalitățile software cât și hardware sunt disponibile îndată ce acestea sunt anunțate de compania producătoare și vin odată cu actualizarea sistemului de operare. 4. Ușurința și calitatea testării. Pe lângă instrumentele remarcate în punctul unu, există o gamă largă de utilități pentru monitorizarea consumării resurselor hardware și testării. În primul rând, toți parametrii în timpul rulării aplicației sunt controlați automat. Dacă aplicația începe să consume mai multe resurse CPU sau RAM acesta nu va trece neobservat. În al doilea rând, o mulțime mare de teste automate pe scară largă care verifică fiecare metodă din aplicație. Dacă o parte din aplicație nu mai funcționează corespunzător din cauza unor modificări de cod, noua versiunea, pur și simplu, nu va fi compilată, iar programatorul va vedea imediat motivul. În al treilea rând, există ample oportunități in integrarea sistemelor de monitorizarea a erorilor la distanță. 5. Suport din partea magazinelor de aplicații. Producătorii sistemelor de operare (Apple și Google) sunt interesați ca utilizatorii să aibă cea mai bună experiență în urmă utilizării produselor lor. Asta ar însemna că aplicația ar trebui să arate și să funcționeze cât mai bine posibil. De exemplu, dacă aplicația conține imagini de dimensiuni mici care se văd neclar pe telefoanele cu ecran mare atunci această aplicație nu va fi acceptată în magazinul de aplicații. Dacă aplicația funcționează prea lent (de exemplu afișează o listă de elemente timp de 10-20 secunde) aceasta nu va fi primită. Totul ar trebuie să fie rapid, frumos și comod. Dacă careva din parametri nu sunt îndepliniți sau sunt prea mici aplicația nu va fi trecută în magazin.
13 2.4. Analiza comparativă a tehnologiilor pentru dezvoltarea aplicațiilor cross-platform La momentul de față există o serie de soluții de platforme care oferă dezvoltare cross-platform, fiecare din ele având avantajele și dezavantajele sale. Mai jos vor fi analizate cele mai populare și performante tehnologii de dezvoltare cross-platform la momentul de față. React Native este un framework JavaScript care a fost lansat de Facebook în 2015[9] și a produs o adevărată revoluție pe piața de dezvoltare a aplicațiilor cross-platform. Având doar câțiva ani de existență, acesta este deja una dintre cele mai populare platforme. React Native se bazează pe framework-ul web React ceea ce este un punct forte pentru dezvoltatorii care cunosc acest framework. În tabelul 2.1 sunt prezentate avantajele și dezavantajele platformei React Native. Avantaje Dezavantaje • Folosește componente native Android și iOS. • Schimbările în cod se pot vedea în timp real. • Se bazează pe conceptele din React. • Comptabilitate cu codul nativ. • Accesul la interfețele dispozitivului se asigură prin module (camera, bluetooth, localizare). • Viteza și simplitatea dezvoltării. • Inconsistența actualizărilor. • Tehnologie relativ nouă. Tabelul 2.1 (Avantajele și dezavantajele React Native) Xamarin a fost lansat în 2011 ca un framework independent de dezvoltare cross-platform, dar ulterior a fost achiziționat de Microsoft, oferindu-i un suport mai solid în continuare[10]. Acesta permite crearea unei singuri logici de aplicație folosind C# și .NET. Platforma Xamarin este reprezentată de o mulțime de sub platforme. Aceste sub platforme joacă un rol important, prin intermediul lor aplicațiilor pot trimite solicitări către interfețele dispozitivului. Se definește interfața utilizator, se cuplează cu logica scrisă în C# și toate asta vor funcționa pe Android, iOS și Windows Phone. Tabelul 2.2 prezintă avantajele și dezavantajele platformei Xamarin.
14 Avantaje Dezavantaje • Comunitate mare de programatori care este în curs de dezvoltare. • Dezvoltatorii de aplicații pot folosi TestCloud pentru testarea automată a aplicațiilor. • Instrumente cunoscute pentru programatorii care cunosc C# și .NET. • Aplicația va arăta identic pe diferite sisteme. • Codul scris poate fi reutilizat. • Definirea interfeței grafice este cu mult mai ușoară comparativ cu definirea interfeței native în iOS folosind constrângerile. • Unele tipare de interfață sunt greu de implementat. • Nu este recomandată pentru aplicațiile care conțin elemente de grafică complexe. • Greu de combinat cu modulele de cod nativ. Tabelul 2.2 (Avantajele și dezavantajele platformei Xamarin) PhoneGap permite crearea aplicațiilor mobile utilizând tehnologiile web standart (HTML5, JavaScript și CSS3). Drept urmare, aceasta a adus la o creștere a popularității platformei. Cu ajutorul acesteia pentru dezvoltarea aplicațiilor nu e nevoie de a folosi limbaje precum: Java pentru Android sau Objective-C pentru iOS. PhoneGap permite compilarea concomitentă pentru iOS, Android și Windows Phone, fără necesitatea de a instala vreun instrument SDK. În tabelul 2.3 sunt prezentate avantajele și dezavantajele framework-ului PhoneGap. Avantaje Dezavantaje • API simplu de utilizat, familiar pentru cei care cunosc HTML, CSS3 și JavaScript. • Posibilitatea a de a utiliza orice librăriei JavaScript (JQuery, Prototype). • Suport pentru toate platformele mobile. • Unele plugin-uri sunt învechite. • Interfața utilizator rulează în browser ceea ce creează un disconfort comparativ cu rularea nativă. Tabelul 2.3 (Avantajele și dezavantajele platformei PhoneGap) Unity este un instrument multiplatformă pentru dezvoltarea aplicațiilor 2D și 3D sau a jocurilor, la fel, e un instrument de creare a conținutului 3D. Aplicațiile create cu ajutorul Unity funcționează pe sistemele de operare Windows, OS X, Linux, Android, iOS, Windows Phone
15 și BlackBerry, la fel pe consolele de jocuri Wii, PlayStation 4 și Xbox One. Mai jos, în tabelul 2.4, sunt prezentate avantajele și dezavantajele Unity. Avantaje Dezavantaje • Perfect pentru crearea jocurilor mobile pentru toate platformele. • Motorul 3D oferă o calitate înaltă fără configurații complexe. • Există o mulțime de plugin-uri gratuite. • Greu de utilizat pentru începători. • Fără acces la codul sursă. • Compilatoarele nu sunt optimizate pentru procesoarele ARM pentru unele dispozitive mobile. Tabelul 2.4 (Avantajele și dezavantajele platformei Unity) Mai jos în tabelul 2.5 sunt prezentate și comparate caracteristicele esențiale ale platformelor enumerate mai sus. React Native Xamarin PhoneGap Unity Limbaje JavaScript, JSX și limbajele native (Objective-C, Java) C#, Xaml JavaScript, HTML5, CSS3 și limbajele native (Java, Objective-C) C#, UnityScript, Boo Platformele suportate iOS, Android, Windows, Web iOS, Android, Windows Phone, Windows Android, iOS, Windows Phone, Blackberry, WebOS, Symbian, Bada, Ubuntu, Firefox OS Android, iOS, Windows Phone, Tizen, PS4, Xbox One Preț Gratis Versiunea comercială cu plată Versiunea gratis și versiunea completă Versiunea profesională cu plată Open Source Da Nu Da Nu UI Nativ Nativ Web UI Canvas Tabelul 2.5 (Compararea platformelor cross-platform) În concluzie, se poate remarca că dezvoltarea aplicațiilor native are o serie de avantaje din punctul de vedere a calității interfeței create. Cu toate acestea există domenii unde folosirea platformelor cross-platform este justificată: jocurile mobile și prototipizarea proiectelor.
16 Jocurile moderne sunt scrise în mare parte în tehnologii multiplatformă, acest lucru accelerează foarte mult dezvoltarea fără deteriorarea căliții, deoarece în acest caz se folosesc framework-uri grafice specializate (cel mai popular fiind Unity). Dacă un proiect are necesitatea de a fi implementat rapid pentru a testa unele lucruri și este necesar ca proiectul să ruleze pe mai multe platforme atunci dezvoltarea cross-platform reprezintă cea mai optimă decizie. În ceea ce primește framework-urile, nu există o soluție perfectă, fiecare are avantajele și dezavantajele sale. Totul depinde de sarcinile care se definesc pentru aplicație. Pentru dezvoltarea aplicației descrisă în acest proiect a fost ales framework-ul React Native. Dezvoltarea cu ajutorul acestui framework este simplă și rapidă, mai ales pentru cei care cunosc deja React. Există o mulțime de module care oferă funcționalitate nativă sau chiar se pot integra perfect cu cod scris nativ pentru fiecare dintre platforme.
17 TEHNOLOGII UTILIZATE Una din cele mai importante elemente în procesul de dezvoltare software este alegerea tehnologiilor, limbajelor de programare și a mediului de dezvoltare corect și potrivit. Mai jos vor fi prezentate tehnologiile care au fost folosite pentru crearea aplicației mobile. Acestea au fost alese după gradul de comoditate, performanță și familiaritate. 3.3. JavaScript JavaScript este limbajul de programare a web-ului. Majoritatea site-urilor web moderne utilizează JavaScript și toate browser-ele web moderne (de pe desktop, console de jocuri, tablete și telefoane mobile) include un interpretor JavaScript, ceea ce face din JavaScript cel mai omniprezent limbaj de programare din istorie. JavaScript face parte din triada de tehnologii care toți dezvoltatorii de pagini web trebuie să o învețe: HTML specifică conținutul paginii web, CSS specifică prezentarea paginii web, iar JavaScript specifică comportamentul paginii Web. JS schimbă aspectului paginii prin manipularea DOM-ului (Document Object Model) care reprezintă un arbore format din toate elementele care se afișează pe pagina web. JavaScript, numit în continuare și JS, este un limbaj de programare de nivel înalt, interpretat (compilat în timp) și netipizat. Acesta își derivă sintaxa din Java, funcțiile de primă clasă din Scheme și moștenirea se bazează pe prototipuri din Self[11]. JS rulează pe un singur thread și este dinamic. E rapid, accesibil și potrivit pentru începători. E cel mai cunosc ca un limbaj de scriptat pe browser, dar în zilele de astăzi este utilizat peste tot. JS este utilizat cât pe partea de client, cât și pe server (node.js). Acesta rulează peste tot de la browsere până la servere puternice. Acest lucru îi oferă un avantaj față de alte limbaje care nu sunt atât de universale. Fără îndoială, JavaScript este unul din cele mai populare și folosite limbaje de programare la momentul de față. Aceasta se datorează comunității mari de programatori JS care susțin în mod activ limbaj, omniprezenței web-ului și a universalității limbajului. Avantajele JavaScript în dezvoltarea unei aplicații mobile cross-platform:
18 • Fiind unul din cele mai populare limbaje de programe, pentru JavaScript există o mulțime de librării și module scrise de comunitate care se află în acces deschis și se pot folosi pentru dezvoltarea proiectului. • JavaScript este destul de ușor de învățat. Poate fi învățat în termen scurt. • De obicei, nu se utilizează librării mari în lucru cu JavaScript care sunt destul de complexe, astfel se poate crește complexitatea proiectului într-un mod mai ușor și a se învăța în curs alte librării. • Pentru crearea aplicației mobile nu e nevoie de cunoștințe specifice în dezvoltarea aplicațiilor mobile și a SDK-urilor lor. Sunt de ajuns cunoștințele de dezvoltare a unei aplicații web cu ajutorul JavaScript. • O bază de cod comună pentru mai multe proiecte. Se poate utiliza aceeași funcționalitate pentru aplicația web, server și mobilă. 3.2. React React este o librărie JavaScript open source pentru crearea interfețelor utilizator. A fost creată de Facebook în 2013[12]. React se folosește în construcția paginilor web formate dintr-o singură pagină sau în dezvoltarea aplicațiilor mobile. Aceasta a fost creat pentru a simplifica lucrul cu DOM-ul din browser. React are un API vast și ușor de înțeles. Pentru a putea lucra cu React e nevoie doar de a înțelege o serie de termeni și care sunt diferențele dintre aceștia. Conceptul de bază al React îl reprezintă componentele. Tot codul React este format din entități numite componente. Componentele se pot insera în DOM cu ajutorul librăriei React DOM. Acestea se pot defini sub formă de clasă (figura 3.1) sau sub formă de funcție (figura 3.2). Ambele abordări acceptă un obiect de parametri numit props. În figura 3.3 este prezentat un exemplu în care o componentă React se redă în DOM-ul browser-ului. Figura 3.1 (Declararea unei componente sub formă de clasă)
19 Figura 3.2 (Declararea unei componente sub formă de funcție) Figura 3.3 (Redarea unei componente în DOM) React folosește o extensie a sintaxei JavaScript, numită JSX. Aceasta seamănă foarte mult cu HTML și se folosește pentru structurarea componentelor în React. Componentele pot fi scrise și în JavaScript pur, dar pentru comoditatea și simplitatea în dezvoltare se folosește JSX.[13] Performanța și viteza React se datorează folosirii unei tehnici sub numele de DOM virtual. React creează un analog al arborelui DOM real din componente și îl prezintă în browser. Acesta urmărește în timp real modificările din DOM-ul virtual și le schimbă în DOM-ul real eficient, schimbându-se doar elementele ce au fost actualizate. Modificările din DOM-ul virtual sunt generate de două elemente, de starea componentei (state) și de proprietățile primite (props). Proprietățile sunt primite de la componentele părinte, iar starea este definită de variabilele sale locale. Starea aplicației se actualizează cu ajutorul funcției setState. Fiecare componentă din React are un ciclu de viață, de exemplu crearea componentei, montarea ei în DOM, demontarea din DOM. React permite executarea codului definit de programator în diferite etape de viață a unei componente. În figura 3.4 sunt prezentate ciclurile de viață a unei componente React.
20 Figura 3.4 (Ciclurile de viață a unei componente) Componenta conține trei perioade mari de cicluri de viață. Acestea sunt: montarea, actualizarea și demontarea. Montarea unei componente reprezintă adăugarea ei în DOM-ul browser-ului. Această etapă conține următoarele cicluri de viață: • Constructor. În cazul în care componenta este definită sub formă de clasă, prima funcție apelată este funcția constructor, aceasta se execută înainte de montare. Constructorul de obicei se folosește pentru inițializarea stării aplicației. • Render. Această metodă este obligatorie pentru orice componentă, aceasta face tot lucru React și scopul ei principal este să returneze JSX. • ComponentDidMount. Această metodă este apelată după ce componenta a fost redată (afișată în DOM) pentru prima oară. De obicei aceast ciclu de viață se folosește pentru a încărca date de pe serverele web sau alte calcule asincrone. Astfel încât DOM-ul să nu fie blocat cu așteptarea execuției acestor funcții. Actualizarea componentei semnifică reîmprospătarea ei cu date noi. Aceasta are loc când se actualizează starea aplicației prin setState sau primirea proprietăților (props) noi. Această etapă include execuția a doua evenimente: • Render. Aceeași metodă descrisă mai sus. • ComponentDidUpdate. Această metodă este similară cu componentDidMount, diferența este că aceasta se apelează de fiecare dată după actualizare și nu numai după prima. Această metodă se folosește pentru a salva modificările făcute în DOM.
21 Demontarea este pasul în care componenta este ștearsă din DOM. • ComponentWillUnmount. Această metodă este apelată după ce componenta a fost demontată sau distrusă. Se folosește pentru curățire, de obicei, pentru a închide socket-urile de rețea deschide sau a dezabona ascultătorii de evenimente. Până la apariția React hooks starea și ciclurile de viață a componentei se puteau controla doar în clase. Cu ajutorul hooks se poate folosi starea aplicațiile cu useState și ciclurile de viață cu useEffect. Popularitatea React are o serie de motive, această librărie este compactă și prezintă performanțe înalte, mai ales atunci când se lucrează cu date care se schimbă rapid. Datorită structurii sale bazate pe componente, codul scris cu React este modular și reutilizabil. 3.3. React Native React Native este un framework pentru dezvoltarea aplicațiilor mobile pentru iOS și Android dezvoltat de compania Facebook[9]. La baza acestuia stă librăria JavaScript – React care se folosește în dezvoltarea aplicațiilor web. Dar, în loc, de browsere aceasta vizează platformele mobile. Cei familiarizați cu React pot folosi React Native pentru a scrie aplicațiile mobile simplu și rapid, folosind toate comoditățile și avantajele unei baze de cod comune în JavaScript. Procesul de dezvoltare a rămas același. Diferențele doar țin de componentele utilizate, de exemplu pentru web se folosește elementul div, iar pentru React Native – View. Cunoașterea limbajelor de programare Objective-C sau Java poate fi utilă, dar nu este obligatorie. Dacă programatorul are o experiență de lucru cu React, atunci fără multe eforturi acesta se va obișnui și cu React Native. Primul lucru ce este surprinzător despre React Native este faptul că acesta este cu „adevărat” nativ. În majoritatea cazurilor soluțiile JavaScript pentru dezvoltarea aplicațiilor mobile doar ambalează codul JS într-un WebView. Ele pot simula un comportament nativ, de exemplu o animație, dar totuși aceasta rămâne în mare parte o aplicație web. În React o componentă descrie faptul cum aceasta arată, iar apoi librăria are grijă să-l redea. Aceste două funcții sunt separate de un nivel de abstractizare clar. Dacă e nevoie de a reda elementele pentru web, atunci se folosesc tag-uri HTML. Acest nivel de abstractizare se folosește și pentru afișarea componentelor în iOS și Android (figura 3.5). React Native apelează API-urile corespunzătoare din SDK-urile fiecărei platforme în parte.
22 Figura 3.5 (Prezentarea principiului de abstractizare) [9] Codul scris cu React Native va semăna izbitor de mult cu JavaScript, CSS și HTML. În loc să se compileze în codul native, React Native preia aplicația scrisă în JS și o rulează folosind motorul JS al platformei respective fără a bloca thread-ul principal pe care rulează interfața utilizator. Astfel se obține avantajele performanței și comportamentului nativ fără a fi nevoie de a scrie în Objective-C sau Java. Comparativ cu dezvoltarea nativă sub iOS și Android, React Native are o serie de avantaje. Din motivul că aplicația este formată în mare parte de cod JavaScript, se pot folosi avantajele dezvoltării web. De exemplu, pentru a vedea schimbările aduse în cod se poate „reîmprospăta” aplicația în timp real fără a fi nevoie de a aștepta compilarea tradițională. Pe parcursul întregii perioade de dezvoltare și întreținere a proiectului folosind acest framework, programatorul folosește limbajul de programare JavaScript. Dacă este necesar codul se poate compila în formatele de aplicații native, apk pentru Android și ipa pentru iOS care pot fi încărcate mai târziu în magazinele de distribuție, App Store și Google Play. Pentru compilarea aplicațiilor este nevoie de SDK-ul ambelor platforme. În acest caz, pentru dezvoltarea pentru iOS este nevoie de un calculator care lucrează pe sistemul de operare macOS ceea ce reprezintă o limitare inevitabilă pentru majoritatea dezvoltatorilor. Iar dacă se dorește compilarea doar pentru Android atunci SDK-ul acestuia se poate instala pe orice platformă, Windows, Linux, macOS.
23 3.4. Flexbox Pentru simplificarea și creșterea performanței redării componentelor React pe platformele native se folosește o versiune de CSS simplificată. Aceasta nu diferă mult de versiunea CSS care se utilizează în browser. De exemplu, dacă pentru browser am avea background-color, pentru React Native ar fi backgroundColor. Stilizarea textului, culorilor, spațierii și a bordurilor se fac la fel ca pe browser. Diferența ține de faptul cum sunt poziționate elementele, în cazul nostru, pe ecranul telefonului mobil. Pentru aceasta se folosește Flexbox. Poziționarea elementelor dintr-o aplicație mobile scrisă cu React Native se face cu Flexbox, cu ajutorul acestor elemente se poate asigura o poziționare a elementelor perfect pe orice dimensiune de ecran. Cea mai utilizată combinație de proprietăți sunt flexDrection, alignItems și justifyContent[14]. • FlexDirection definește direcția în care să fie aranjate elementele de pe ecran, această direcție mai este numită și axa principală. Valoarea implicită pentru această proprietate este column (alinierea elementelor de sus în jos). Pentru alinierea elementelor de la dreapta la stânga se folosește valoarea row. • JustifyContent descrie faptul cum să fie aranjate elementele pe axa principală. Această proprietate poate primi valorile flex-start (poziționare la început, valoare implicită), flex-end (poziționare la sfârșit), center (poziționare la mijloc). • AlignItems descrie faptul cum să fie aranjate elementele pe axa secundară. Axa secundară este perpendiculară pe axa principală. Valorile posibile pentru această proprietate sunt stretch (elementul să ocupe toată lățimea, valoarea implicită), flex-start (poziționare la început), flex-end (poziționare la sfârșit), center (poziționare la centru). Pentru poziționare specifică a unui element în parte se folosește alignSelf (poziționare după axa secundară) și alignContent (poziționare după axa principală). Pentru poziționarea unui element pe ecranul telefonului mobil se mai poate folosi și poziționarea absolută în cazul în care nu se dorește ca elementele să fie afișate în ordinea naturală.
24 3.5. Firebase Firebase este o platformă dezvoltată de Google pentru cererea aplicațiilor web și mobile[16]. Cu ajutorul acesteia se pot construi aplicații rapide, fără a avea grija de infrastructură (server, baze de date). Firebase oferă așa funcționalități ca analitică, baze de date, mesagerie etc. Acesta se bazează pe infrastructura Google, astfel aplicațiile se pot scala automat fără a fi nevoie de vreo intervenție cât de mare nu ar fi aplicația. Serviciile Firebase funcționează excelent individual, dar din cauza că acestea împărtășesc date comune reprezintă un avantaj. Serviciul de bază este sistemul de gestiune a bazelor de date NoSQL în cloud care permite dezvoltatorilor păstrare și sincronizarea datelor între mai mulți utilizatori. Platforma se poate integra foarte ușor cu aplicațiile mobile care rulează pe sisteme de operare iOS și Android. Dispune de un API pentru JavaScript, NodeJS, Objective-C, Java. Se poate folosi și direct prin cereri de tip REST lucrând cu framework-uri ca React, Angular, Vue. Printre alte servicii oferite de această platformă se remarcă serviciul de găzduire a fișierelor (așa ca HTML, CSS și JavaScript), sistem de autentificare pentru utilizatori cu suportul de conectare prin (Facebook, Google, Twitter, număr de telefon mobil). Firebase conține o serie de servicii care se împart în trei categorii: dezvoltare, calitate și creștere[15]. Aplicațiile din categoria dezvoltare sunt: • Cloud Firestore. Stocarea și sincronizarea datelor între toate dispozitivele la nivel global. • Cloud Functions. Rularea funcțiilor pe servere fără a avea grijă de infrastructura acestora. • Authentication. Autentificare simplă și securizată a utilizatorilor. • Hosting. Oferirea aplicațiilor web cu rapiditate și securitate de pe server. • Cloud Storage. Stocarea și servirea fișierelor. • Realtime Database. Permite stocarea și sincronizarea datelor din aplicație. • Firebase ML. Învățare automată pentru aplicațiile mobile. Aplicațiile din categoria calitate sunt: • Crashlytics. Raportarea erorilor și a problemelor în timp real cu posibilitatea de a le prioritiza și remedia. • Perfomance Monitoring. Monitorizarea performanțelor aplicației.
25 • Test Lab. Testarea aplicațiilor găzduite pe platforma Google. • App Distribution. Distribuirea aplicațiilor. Aplicațiile din categoria creștere sunt: • In-App Messaging. Mesaje contextuale pentru utilizatorii aplicației. • Google Analytics. Analitica privind utilizarea aplicației. • Predictions. Segmentarea inteligentă a utilizatorilor bazată pe comportamentul prezis. • A/B Testing. Optimizarea interacțiunii cu aplicația prin experimente. • Cloud Messaging. Trimiterea mesajelor și notificărilor vizate. • Remote Config. Modificarea aplicații fără realizarea unei versiuni noi. • Dynamic Links. Utilizarea legăturilor personalizate. În proiectul de față s-au folosit următoarele servicii Firebase: Cloud Firestore pentru stocarea datelor din aplicație, Authentication pentru autentificarea utilizatorilor și Cloud Functions pentru rularea funcțiilor pe server. 3.6. Firebase Firestore Firestore este un serviciu din suita Firebase, acesta permite stocarea, sincronizarea și accesarea datelor de pe aplicațiile mobile sau aplicațiile web. Firestore este în esență un sistem de baze de date flexibil și scalabil NoSQL. În comparație cu bazele de date tradiționale, SQL, acestea nu au o formă rigid definită sub formă de tabele și relații dintre tabele. Structura bazei de date este formată din colecții și documente. Colecțiile din Firebase sunt asemănătoare unor array-uri și conțin doar documente. Documentele sunt asemănătoare unor obiecte și pot conține mai multe timpuri de date, șiruri de caractere, valori booleene, numere, array-uri, obiecte. Un document poate conține alte colecții, astfel se asigură o structură ierarhizată a datelor care se pot accesa cu ușurință prin interogări. În Firestore se utilizează interogări specializate pentru a prelua toate documentele din baza de date sau un document specific dintr-o colecție care corespund parametrilor de interogare. Firestore folosește sincronizarea datelor pentru a actualiza datele pe orice dispozitiv conectat. Pe lângă aceasta, interogările simple singulare, la fel, sunt eficiente. Datele se pot sorta, filtra și limita prin interogări, astfel se poate implementa funcționalitate de paginare. Datele din aplicație se pot menține actualizate în timp real prin înregistrarea unui ascultător care se va
26 apela de fiecare dată când se actualizează datele. Interogările sunt disponibile prin SDK-urile native iOS, Android sau web. Datele din baza de date care se utilizează frecvent se memorizează în memoria cache, astfel datele se pot scrie, citi, asculta și interoga chiar și când dispozitivul este offline. Iar când conexiunea la internet revine, Firestore sincronizează orice modificare locală cu baza de date de pe server. 3.7 Firebase Authentication Majoritatea aplicațiilor au nevoie de a cunoaște identitatea utilizatorului care folosește aplicația. Cunoașterea identității utilizatorului permite aplicației să salveze în siguranță datele utilizatorului în cloud și să ofere aceeași experiență personalizată pe toate dispozitivele utilizatorului. Autentificare Firebase reprezintă un serviciu backend, un SDK ușor de folosit, și un UI gata făcut pentru a autentifica utilizatorii în aplicație. Autentificare se poate face prin parolă, număr de telefon sau vreun furnizor de identitate popular precum Google, Facebook, Twitter și altele. Autentificare Firebase se integrează perfect cu alte servicii Firebase și utilizează standardele din industrie, cum ar fi OAuth 2.0 și OpenID Connect, astfel încât acesta se pot ușor integra cu sistemul backend personalizat[16]. Pentru a conecta un utilizator în aplicație, se folosesc datele credențiale de autentificare de la utilizator. Aceste date pot fi reprezentate de adresa de email și parola utilizatorului sau de un token OAuth de la unii din furnizorii de identitate. Serviciile Firebase verifică aceste date credențiale și returnează un răspuns. După o conectare reușită, se pot accesa informațiile de bază ale utilizatorului și se poate controla accesul utilizatorului la datele stocate în alte servicii Firebase. În mod implicit, utilizatorii autentificați pot citi și scrie datele în baza de date Firestore. De asemenea, se poate utiliza tokenul de autentificare pentru serviciile de backend proprii.
27 3.8 Firebase Cloud Functions Funcțiile Cloud din Firebase oferă posibilitatea de a rula automat codul de backend în răspuns la evenimentele declanșate de funcțiile Firebase și cererile HTTPS fără server. Funcțiile se pot scrie cu ajutorul limbajului de programare JavaScript sau TypeScript și sunt stocate în Google cloud și rulează într-un mediu gestionat și securizat[17]. Nu este nevoie de servere proprii sau gestionare complicată. După scrierea și implementarea funcțiilor, serverele Google încep să gestioneze funcțiile imediat. Funcția se poate declanșa cu o solicitare HTTP, sau în cazul funcțiilor de fundal, acestea vor asculta evenimente din cadrul Firestore și vor rula funcțiile când acestea sunt declanșate. Acest serviciu este scalabil, astfel dacă încărcarea crește sau scade, serverele Google vor răspunde prin scalarea rapidă a numărului de instanțe de servere virtuale care sunt necesare pentru a rula funcțiile. Fiecare funcție rulează izolat, în propriul mediu cu propria sa configurație. Funcțiile din Cloud se declanșează în urma unor evenimente din baza de date Firestore. Astfel, se pot scrie funcții care vor rula după ce se va scrie ceva în baza de date, actualiza sau șterge date. În acest mod, se pot manipula adăugător datele pe partea de backend fără a deține și întreține un server.
28 DEZVOLTAREA APLICAȚIEI Proiectul de față descrie dezvoltarea unei aplicații mobile cu ajutorul framework-ului React Native. Aplicația este destinată persoanelor care doresc să reducă risipa alimentară. Pentru folosirea aplicației utilizatorul trebuie să se autentifice/creeze un cont. Contul se va folosi pentru a putea identifica utilizatorul. După autentificare este disponibilă navigarea între trei ecrane: Alimente, Gătit și Rețete. Primul ecran reprezintă lista de produse alimentare pe care utilizatorul le are. Fiecare produs din listă este descris prin numele său și data de expirare. Produsele sunt aranjate în ordinea în care urmează să expire. În partea de dreapta-jos se află un buton de adăugare. Alimentele se pot adăuga prin două metode, prima metodă este introducerea numelui și datei de expirare a produsului, a doua metodă prin scanarea codului de bare a produsul. În al doilea caz câmpul de nume al produsului se auto populează, rămâne de introdus doar data de expirare. Al doilea ecran este format din lista rețetelor care se pot găti din alimentele disponibile (afișate în prima pagină) și toate rețele din baza de date. În listă sunt afișate doar numele rețetei, după atingerea uneia din ele se navighează spre ecranul rețetei alese. Ecranul rețetei conține lista cu toate produsele care sunt necesare pentru pregătirea mâncării selectate și a modului de preparare. Al treilea ecran este format din lista personală a rețetelor utilizatorului. În listă sunt afișate doar rețetele adăugate de utilizator. În partea de dreapta-jos se află un buton de adăugare a rețetei. Pentru adăugare rețetei este nevoie de a completa denumirea ei, fiecare ingredient de care este nevoie pentru pregătirea acestei rețete și modul de preparare a ei. 4.1. Setarea mediului de dezvoltare a aplicației mobile Alegerea și setarea mediului de dezvoltare este una din cele mai importante și vitale decizii pentru că aceasta determină capacitățile de dezvoltare a aplicației mobile. În cadrul acestui proiect aplicația mobilă a fost dezvoltată utilizând sistemul de operare macOS Catalina. Folosirea acestui sistem de operare permite compilarea și rularea aplicațiilor mobile sub platforma iOS. Sistemul de operare vine cu terminalul preinstalat sub gestiunea zsh. Zsh este un shell Unix care va fi folosit ca interpretor de comenzi shell[18].
29 În timpul dezvoltării proiectului s-a folosit sistemul de control al versiunilor – Git. Proiectul este găzduit pe GitHub sub forma unui repositoriu închis. Pentru managerul de pachete Yarn s-a instalat Node.js. Cu ajutorul acestuia se pot instala/actualiza și șterge module JavaScript, acestea sunt necesare pentru funcționarea React Native. Ca editor de cod se va folosi în mare parte programul Visual Studio Code. Acesta este destul de rapid și oferă o gamă largă de extensii care se pot instala independent. Editorul se integrează perfect cu Git, commit-urile se pot face prin interfața editorului sau prin shell. Pe lângă editorul Visual Studio Code se vor folosi și editoarele native pentru dezvoltarea mobilă, Xcode pentru iOS și Android Studio pentru Android. Pentru compilarea proiectului este nevoie de a instala SDK-urile native. Xcode se poate instala din magazinul de aplicații macOS – App Store, odată cu instalarea editorului se instalează întreg mediu de dezvoltare care include SDK-ul și Simulatorul. Pe lângă aceasta se mai instalează și managerul de pachete software pentru iOS – CocoaPods. Android Studio se poate instala de pe siteul dezvoltatorilor Android. Acesta include SDK-ul Android și Emulatorul. Urmează instalarea framework-ului React Native, odată ce avem mediul setat pentru dezvoltarea nativă. Inițializarea unui proiect nou React Native se poate face cu ajutorul shell-ului cu comanda npx react-native init NumeProiect. NPX este asemănător NPM, doar că în cazul în care modulul nu este instalat acesta se descarcă de pe internet. Această comandă va crea toate fișierele necesare pentru un proiect de start și va instala toate dependințele necesare, atât JavaScript prin NPM, atât și iOS prin CocoaPods. După finalizarea rulării comenzii de inițializare se poate porni proiectul de start cu ajutorul comenzii npx react-native start. Această comandă de shell pornește Metro Bundler-ul acesta este responsabil pentru cuplarea codului JavaScript cu proiectul nativ. Însăși pentru rularea aplicației native este nevoie de a rula una din comenzi npx react-native run-ios sau npx react-native run-android, în primul caz se va rula simulatorul de iOS, iar în al doilea emulatorul de Android (figura 4.1). Aplicația se pornește implicit în simulator sau emulator, pentru rularea aplicației pe un dispozitiv real este nevoie de a conecta acest dispozitiv la calculator, apoi de rulat proiectul din editorul nativ (Xcode sau Android Studio), acolo este prezentă opțiunea de a alege pe ce dispozitiv să ruleze aplicația.
30 Figura 4.1 (Stânga – simulator iOS; dreapta – emulatorul Android; rulând proiectul inițial React Native) După rularea proiectului inițial pe ambele platforme și convingerea că ambele funcționează perfect atât pe iOS, cât și pe Android. Următoarea etapă reprezintă crearea fișierelor și directoarelor comune. Acestea reprezintă fișierele care se utilizează cel mai des și directoarele de bază. • Fișierul de temă. Include toată gama de culori folosită în aplicație, familia de fonturi, dimensiunea fonturilor și dimensiunile de spațiere. • Fișierul de constante. Include constantele des folosite în aplicație, cum ar fi denumirile ecranelor. • Fișierul de utilități. Include funcțiile des folosite în aplicație, de exemplu funcția de calcul al lățimii barei de status.
31 • Directoriul de componente. Folosind framework-ul React Native, componentele reprezintă o entitate vitală pentru aplicație. • Directoriul de ecrane. Aplicație este formată din ecrane și toate ecranele se vor păstra în acest director. • Directoriul de navigare. În acest directoriu se va afla toată logica de navigare între ecrane. • Directoriul de API. În acest director se va afla toată logica de manipulare cu API, în cazul de față, Firebase. 4.2. Implementarea stivei de autentificare Stiva de autentificare este format din următoarele ecrane: • Ecranul de autentificare. În acest ecran utilizator poate introduce adresa de email și parola pentru a se autentifica în aplicație. • Ecranul de înregistrare. În acest ecran utilizatorul poate introduce adresa de email, parola și confirmarea parolei pentru a se înregistra. • Ecranul de resetare a parolei. În acest ecran utilizatorul poate introduce adresa de email pentru a reseta parola. Pentru navigarea între aceste ecrane este nevoie de un modul care oferă posibilitatea de a crea logica de navigare pe ambele platforme, iOS și Android. Cel mai potrivit modul este react-navigation, acesta se instalează cu ajutorul managerului de pachete yarn din shell. Navigarea între ecranele de autentificare se face cu ajutorul navigării de tip stivă. Acesta oferă o modalitate prin care aplicația poate face tranziția între ecrane, astfel încât fiecare ecran nou deschis este plasat deasupra stivei. Ecranul principal este reprezentat de ecranul de autentificare, iar ecranul de înregistrare și resetare a parolei se vor plasa deasupra stivei de navigare când vor fi deschide. Pentru logica de API este nevoie de configurat proiectul Firebase. Aceasta se creează și se configurează din consola Firebase care are forma unui site web. După crearea acestuia se livrează câte un fișier de configurări pentru fiecare platformă care trebuie plasat în directoarele respective pentru iOS și Android. Urmează instalarea pachetului Firebase care se face cu ajutorul yarn prin comanda yarn add @react-native-firebase. Acum există acces spre serviciile firebase cu ajutorul API, rămâne de adăugat următoarele interogări spre serviciul de autentificare: autentificare, înregistrare și resetare parolă.
32 După setarea logicii de autentificare urmează definirea ecranelor de autentificare. Fiecare ecran din React Native, de obicei, este format din componente. Din acest motiv, de la început, e nevoie de creat unele componente de bază. • Spinner. Aceasta componentă indică o stare de încărcare, se afișează în timpul operațiilor asincrone (interogări API). Astfel, încât utilizatorul să înțeleagă că ceva se întâmplă și nu doar vede un ecran blocat cât timp se execută o interogare. Aceasta folosește componenta de bază din React Native – Activity Indicator. Componenta este reprezentată în figura 4.2.
Figura 4.2 (Componenta Spinner) • ErrorAlert. Această componentă apare sub formă de modal și semnifică întâmplarea unei erori, în mod normal după execuția unei operații asincrone. Ca de exemplu, lipsa conexiunii la rețea, time-out, lipsa drepturilor de accesare, parolă greșită etc. Componenta primește prin props mesajul de eroare pe care să-l afișeze și callback-ul pe care să-l apeleze în momentul apăsării butonului Ok, în mod implicit butonul nu face nimic. Un props opțional este funcția de callback pentru butonul de anulare, în cazul în care această se trimite se mai afișează butonul respectiv și se apelează funcția trimisă. Aceasta folosește componenta de bază din React Native – Alert. În figura 4.3 este reprezentată această componentă.
Figura 4.3 (Componenta ErrorAlert)
33 • TextField. Această componentă reprezintă un câmp de text. Este folosită în momentul în care pe un ecran se dorește introducerea unui text. Componenta primește o serie de props, printre care: numele câmpului, referința ei (pentru a focusa pe câmp), stilul, mesajul de eroare pe care să-l afișeze în cazul apariției uneia și alte proprietăți implicite ale componentei de bază. Componenta de bază este TextInput. În figura 4.4 este reprezentată componenta TextField afișând o eroare. Figura 4.4 (Componenta TextField afișând o eroare) Ecranul de autentificare este primul ecran pe care-l vede utilizatorul în cazul în care nu este autentificat (figura 4.5). Acesta este format din următoarele componente: • Text. Se folosește pentru a afișa titlul ecranului și subtitlul acestuia. Este o componentă de bază. • TextField. Se folosește pentru a introduce adresa de email și parola. Componenta este definită personal. • TouchableOpacity. Această componentă reprezintă butoanele. Butonul de autentificare (interoghează API-ul de autentificare pentru a verifica identitatea utilizatorului), butonul de înregistrare (navighează spre ecranul de înregistrare) și butonul de resetare a parolei (navighează spre ecranul de resetare a parolei). Din punct de vedere logic ecranul de autentificare este definit ca o componentă de tip funcție care conține următoarele constante de stare: • Câmpul de adresă de email. Reprezintă un obiect cu două valori, o valoare reprezintă ceea ce conține câmpul la moment, inițial e gol. Al doilea câmp conține eroarea ce ține de acest câmp, inițial e null. • Câmpul de parolă. Reprezintă aceeași structură ca câmpul de adresă de email. • Loading. Reprezintă o valoare booleană care denotă faptul dacă se execută o operație asincronă. În cazul apăsării butonului de autentificare se apelează o funcție internă care tratează autentificarea. Inițial se verifică dacă câmpul de adresă de email și parolă sunt completate, dacă
34 nu – se setează o eroare pe aceste câmpuri. Dacă câmpurile sunt completate, atunci se setează constanta de loading pe adevărat, astfel se afișează Spinner-ul. Și se interoghează API-ul de autentificare, dacă se primește un răspuns valid, atunci se navighează spre navigatorul aplicației. În cazul în care se returnează o eroare, atunci se verifică dacă această eroare ține de vreun câmp, dacă da – se setează eroarea pe câmp, dacă nu – se afișează eroarea cu ajutorul componentei ErrorAlert. Ecranul de înregistrare este format din următoarele componente (figura 4.5): • Text. Se folosește pentru a afișa titlul ecranului și subtitlul acestuia. • TextField. Se folosește pentru a introduce adresa de email, parola și confirmarea parolei. • TouchableOpacity. Această componentă reprezintă butonul de înregistrare. • Spinner. Reprezintă așteptarea interogării către server. Din punct de vedere logic ecranul de înregistrare este definit ca o componentă de tip funcție care conține următoarele constante de stare: • Câmpul de adresă de email. Conține aceeași structura ca și în cazul ecranului de autentificare. • Câmpul de parolă. Reprezintă aceeași structură ca câmpul de adresă de email. • Câmpul de confirmare a parolei. • Loading. Reprezintă o valoare booleană care denotă faptul dacă se execută o operație asincronă. În cazul apăsării butonului de înregistrare se apelează o funcție internă care tratează înregistrarea. Inițial se verifică dacă câmpul de adresă de email și parolă sunt completate, dacă nu – se setează o eroare pe aceste câmpuri. Apoi se verifică dacă parolele coincid, dacă nu – se setează o eroare pe câmpul de confirmare a parolei. Dacă câmpurile sunt completate și parolele coincid, atunci se setează constanta de loading pe adevărat, astfel se afișează Spinner-ul. Și se interoghează API-ul de înregistrare, dacă se primește un răspuns valid, atunci se navighează spre navigatorul aplicației. În cazul în care se returnează o eroare, atunci se verifică dacă această eroare ține de vreun câmp, dacă da – se setează eroarea pe câmp, dacă nu – se afișează eroarea cu ajutorul componentei ErrorAlert.
35 Ecranul de resetare a parolei este format din următoarele componente (figura 4.5): • Text. Se folosește pentru a afișa titlul ecranului și subtitlul acestuia. • TextField. Se folosește pentru a introduce adresa de email pentru care cont se dorește resetarea parolei. • TouchableOpacity. Această componentă reprezintă butonul de resetare a parolei. • Spinner. Reprezintă așteptarea interogării către server. Din punct de vedere logic ecranul de resetare a parolei este definit ca o componentă de tip funcție care conține următoarele constante de stare: • Câmpul de adresă de email. Conține aceeași structura ca și în cazul ecranului de autentificare. • Loading. Reprezintă o valoare booleană care denotă faptul dacă se execută o operație asincronă. În cazul apăsării butonului de resetare a parolei se apelează o funcție internă care tratează înregistrarea. Comportamentul acestei funcții e la fel ca a celei de autentificare, doar că interogarea spre API se face cu scopul de a reseta parola. În cazul primirii unui răspuns valid după interogare se navighează spre ecranul de autentificare cu notificarea utilizatorului printr-un modal că va primi un email cu instrucțiunile de resetare a parolei. În cazul ecranelor de înregistrare și resetarea a parolei din acestea se poate naviga înapoi spre ecranul de autentificare din motivul că aceste ecrane sunt într-o stivă de navigare. Ecranul de autentificare este de bază, iar ecranul de înregistrare și resetare a parolei vin deasupra stivei la navigare.
36 Figura 4.5 (Stânga – ecranul de autentificare; centru – ecranul de înregistrare; dreapta – ecranul de resetare a parolei) 4.3. Implementarea ecranelor aplicației Odată ce utilizatorul se autentifică în aplicație acesta este redirecționat spre navigatorul aplicației. Acesta este format dintr-un navigator pe taburi care conține trei ecrane: ecranul de alimente, ecranul de gătit și ecranul de rețete. În fișierul de pornire a aplicației se înregistrează un ascultător pentru starea de autentificare a utilizatorului. Luând în vedere aceasta, odată ce se intră în aplicație acest ascultător returnează obiectul de utilizator în cazul în care acesta s-a autentificat sau null dacă nu este autentificat. Dacă se returnează obiectul de utilizator atunci direct se navighează spre navigatorul de aplicație, iar dacă nu se rămâne pe stiva de autentificare. Ecranul de alimente este format din următoarele componente (figura 4.6): • FlatList. Este o componentă de bază din React Native care permite redarea listelor într-un mod performant. Această componentă primește prin props un array cu datele cu care
37 să fie populată lista și o altă componentă care să afișeze însăși elementul din listă. Această listă afișează alimentele. • ActionButton. Este o componentă terță, instalată printr-un pachet cu yarn. Această afișează butonul de adăugare a alimentelor. Odată ce există două metode a adăugare a alimentelor acest buton include alte două butoane (figura 4.7): adăugarea clasică și adăugarea prin scanarea codului de bare.
Figura 4.7 (Butoanele de adăugare a alimentelor) • FoodItem. Este o componentă definită personal. Această reprezintă un element din lista de alimente. Componenta primește prin props datele despre un aliment (numele și data de expirare) și le afișează corespunzător. Pe lângă afișarea numelui și datei de expirare se mai afișează și un marker în dreapta care simbolizează starea alimentului (roșu – produsul expiră astăzi, galben – produsul expiră în următoarea zi, altfel – verde) (figura 4.8). Prin swipe la stânga a unuia dintre elementele listei acesta se poate șterge (figura 4.9). Figura 4.8 (Afișarea unui aliment)
38 Figura 4.9 (Ștergerea unui aliment) • Text. Afișează textului că nu există alimente. • Spinner. Reprezintă încărcarea datelor de pe server. • Header. Este o componentă definită personal. Aceasta reprezintă antetul ecranului și afișează un titlu care se primește ca props. Componenta Header este prezentată în figura 4.10. Figura 4.10 (Componenta Header) Din punct de vedere logic ecranul de alimente este definit ca o componentă de tip funcție care conține o constantă de stare numită food. Aceasta reprezintă un obiect cu două valori, prima valoare reprezintă array-ul de alimente, inițial e gol. A doua valoarea reprezintă starea de încărcare, inițial este setată pe adevărat, deoarece odată cu apariția acestuia ecran se dorește descărcarea alimentelor din baza de date. În cazul în care starea de încărcare este adevărat, atunci se afișeză Spinner-ul. În cazul în care după primirea datelor de la server, array-ul cu alimente este gol, se afișează textul că nu există nici un aliment, altfel se afișează lista de alimente. Pentru descărcarea alimentelor de pe server s-a folosit un ascultător care se abonează la actualizările din baza de date a colecției de alimente. De fiecare dată ce are loc vreo schimbare în colecția de alimente acest ascultător apelează funcția sa de callback. Funcția de ascultător a fost adăugată în fișierul de API, și se numește getFood, aceasta primește doi parametri. Primul parametri reprezintă o funcție de callback care se apelează în cazul primirii cu succes a datelor din colecții de pe server, a doua funcție este o funcție care se apelează în cazul unei erori. GetFood accesează colecția de alimente și le filtrează după uid (câmpul de uid reprezintă id-ul utilizatorul care a adăugat acest aliment), astfel încât utilizatorul să primească doar alimentele lui și le ordonează ascendent după data de expirare.
39 Ecranul de gătit este format din următoarele componente (figura 4.6): • FlatList. Această listă afișează rețetele de gătit. • RecipeItem. Este o componentă definită personal. Aceasta afișează titlul rețetei. Navigarea spre ecranul rețetei se face prin apăsare pe element. • Header. Afișează titlul ecranului. • Text. Afișează textului că nu există rețete de gătit. • Spinner. Reprezintă încărcarea datelor de pe server. Din punct de vedere a logicii este asemănătoare cu ecranul de alimente. Găsirea rețetelor care se pot găti are loc cu ajutorul funcțiilor cloud. Astfel, la adăugarea, ștergerea unui aliment sau la crearea unei noi rețete, pe serverele Google, care găzduiesc funcțiile cloud, se declanșează o funcție de asociere. Această funcție parcurge toate rețetele și verifică dacă utilizatorul curent dispune de toate ingredientele enumerate, dacă da atunci această rețetă este adăugată într-o colecție de gătit. Din colecția de gătit se afișează rețetele disponibile pe ecranul de gătit. Ecranul de rețete este format din următoarele componente (figura 4.6): • FlatList. Această listă afișează rețetele personale. • RecipeItem. Această componentă prezintă rețeta în listă. • Header. Afișează titlul ecranului. • Text. Afișează textului că nu există rețete personale. • Spinner. Reprezintă încărcarea datelor de pe server. • ActionButton. Reprezintă butonul de adăugarea a unei noi rețete personale. Apăsând pe el se navighează spre ecranul cu adăugare rețetei. Din punct de vedere a logicii este asemănătoare cu ecranul de alimente.
40 Figura 4.6 (Stânga – ecranul de alimente; centru – ecranul de gătit; stânga – ecranul de rețete) Ecranul de adăugare a alimentului este format din următoarele componente (figura 4.11): • Text. Se folosește pentru a afișa titlul ecranului și subtitlul acestuia. • TextField. Componentă definită personal. Folosită pentru introducerea denumirii alimentului. • DateTimePicker. Este o componentă terță, instalata ca pachet cu yarn. Aceasta se folosește pentru a oferi un calendar de selectare a datei. Acest lucru reprezintă o încercare, odată ce selectorul de dată pe iOS este sub o formă, iar pentru Android sub altă formă ca modal. Valoare selectată în componentă reprezintă data de expirare a alimentului, valoarea inițială este setată pe ziua de mâine. • TouchableOpacity. Această componentă reprezintă butonul de adăugare a alimentului. • Spinner. Reprezintă așteptarea interogării către server. Din punct de vedere logic ecranul de adăugare a alimentului este definit ca o componentă de tip funcție care conține următoarele constante de stare:
41 • Numele alimentului. Reprezintă un obiect cu două valori, o valoare reprezintă ceea ce conține câmpul la moment, inițial e gol. Al doilea câmp conține eroarea ce ține de acest câmp, inițial e null. • Data de expirare. Valoarea inițial este setată pe ziua de mâine. • Loading. Reprezintă o valoare booleană care denotă faptul dacă se execută interogarea spre server. În cazul apăsării butonului de adăugare a alimentului se apelează o funcție internă care tratează adăugarea. Inițial se verifică dacă câmpul de nume este completat, dacă nu setează o eroare pe aceste câmp. Apoi se setează constanta de loading pe adevărat, astfel se afișează Spinner-ul. Și se interoghează API-ul de Firestore, adăugându-se un nou document în colecția de alimente. Dacă se primește un răspuns valid, atunci se navighează spre ecranul cu alimente. În cazul în care se returnează o eroare, se afișează eroarea cu ajutorul componentei ErrorAlert. Ecranul de alimente și adăugare a alimentelor fac parte din aceeași stivă de navigare, astfel când se deschide ecranul de adăugare acestea se adăuga deasupra. Ecranul de scanare a codului de bare este format din următoarele componente (figura 4.11): • RNCamera. Este o componentă terță. Cu ajutorul acesteia se implementează funcționalitate de camera pe React Native. Se instalează ca pachet cu yarn. Componenta primește prin props o funcție sub formă de callback care să fie apelată când se depistează un cod de bare. • View. Cu ajutorul View-urilor s-a creat un chenar pentru codul de bare. • TouchableOpacity. Buton de navigare înapoi. • Spinner. Reprezintă executarea interogării spre server. Din punct de vedere logic ecranul de scanare a codului de bare este definit ca o componentă de tip funcție care conține constanta de stare care descrie statusul camerei. Inițial statusul camerei este setat pe valoarea de pre vizualizare, în acest caz camera funcționează în mod normal și bordura chenarului este de culoare albă. Odată de modulul de camera depistează un cod de bare, se declanșează funcția responsabilă de a trata un cod de bare. Dacă s-a depistat un cod de bare valid, atunci statusul se schimbă în detectat (imaginea camerei se îngheață și bordurile chenarului devin verzi). Se face o interogare spre Firebase cu codul de bare, dacă se primește un răspuns valid, atunci cu datele primite (numele produsului) se navighează spre
42 ecranul de adăugare a produsului, numele fiind pre completat. În cazul în care nu s-a găsit codul de bare, se afișează un mesaj corespunzător și se propune continuarea scanării unui alt cod de bare sau revenirea la ecranul precedent. Ecranul de adăugarea a unei noi rețete este format din următoarele componente (figura 4.11): • Text. Se folosește pentru a afișa titlul ecranului și subtitlul acestuia. • TextField. Componentă definită personal. Folosită pentru introducerea denumirii rețetei, a ingredientelor (număr dinamic) și a modului de preparare (are setată proprietate de mult linie cu 4 rânduri). • TouchableOpacity. Buton de adăugare a rețetei și a unui nou ingredient. • Spinner. Reprezintă executarea interogării spre server. Din punct de vedere logic ecranul de adăugare a rețetei este definit ca o componentă de tip funcție care conține următoarele constante de stare: • Numele rețetei. Reprezintă un obiect cu două valori, o valoare reprezintă ceea ce conține câmpul la moment, inițial e gol. Al doilea câmp conține eroarea ce ține de acest câmp, inițial e null. • Ingredientele. Acestea reprezintă un array cu obiecte de tipul celor descris în cazul numelui de rețetă. • Modul de preparare. Același obiect ca și în cazul numelui de rețetă. • Loading. Reprezintă faptul că se execută interogarea de adăugare. În dreptul câmpului de ingredient există un buton de adăugare a unui noi câmp de ingredient. O dată ce se adăugă un ingredient în plus (un câmp nou) în dreapta acestuia se află un buton de ștergerea a elementului. Astfel, în mod dinamic se pot seta numărul ingredientelor. În cazul apăsării butonului de adăugare a rețetei se declanșează o funcție internă care verifică ca câmpurile de nume, ingrediente și mod de preparare să fie completate, dacă nu sunt se afișează o eroare pe câmpul respectiv. Constanta de stare loading se setează pe adevărat ceea ce semnifică afișarea Spinner-ului și se apelează funcția de API de adăugare a rețetei în colecția de rețete. Pe lângă nume, ingrediente și mod de preparare a rețetei se mai adăuga și un câmp ce semnifică id-ul utilizatorul, astfel încât să se cunoască cine a adăugat rețeta. În cazul în care adăugarea a avut loc cu succes se navighează spre ecranul de rețete, altfel se afișează mesajul de eroare.
43 Figura 4.11 (Stânga – ecranul de adăugare a alimentului; centru – ecranul de scanare a codului de bare; dreapta – ecranul de adăugare a rețetei) Ecranul rețetei (figura 4.12): este format dintr-o singur componentă – Text. Componentă de bază. Afișează lista de ingrediente care sunt necesare de preparat și modul de pregătire a acesteia. Aceste date sunt primite prin props, de la modulul de navigare. Atunci când se selectează o rețetă navigarea se face prin trimiterea datelor despre aceea rețetă.
Figura 4.12 (Ecranul unei rețetei)
44 CONCLUZII În procesul de scriere a acestei lucrări s-au luat în considerare și analizat principalele moduri și abordări în domeniul dezvoltării aplicațiilor mobile. S-au prezentat și analizat tehnologiile, limbajele de programare și mediile de dezvoltare folosite în procesul de dezvoltarea a unei aplicații mobile. S-a făcut o analiză comparativă a tehnologiilor cross-platform enumerând avantajele și dezavantajele fiecărei în parte. Astfel, s-au parcurs și studiat o gamă largă de tehnologii care permit dezvoltarea aplicațiilor mobile complete, atât pe partea de front-end, cât și back-end. În lucrarea de față s-a propus dezvoltarea unei aplicații mobile de tip cross-platform. În procesul creării aplicației s-au folosite cele mai noi, comode și performante tehnologii. Astfel, ca urmare a finalizării acestui proiect de diplomă s-a reușit dezvoltarea unei aplicațiile mobile pentru minimizarea risipei alimentare. În timpul implementării aplicației a fost creată o interfață plăcută, intuitivă și comodă, în vederea căreia nu va fi dificil pentru utilizator să o folosească. Cu ajutorul acestei aplicații utilizatorii pot duce evidența alimentelor sale, astfel încât pot vedea și primi notificări în vederea expirării alimentelor. Plus la asta pot primi recomandări de rețete de gătit astfel încât alimentele să nu se piardă. Aplicația are un potențial mare de folosință, odată ce-și propune să rezolve una din cele mai stringente probleme ecologie al timpului curent. Evident că, aplicația mai poate fi dezvoltată și îmbunătățită. Se poate îmbunătăți metoda de adăugare a alimentelor prin recunoaștere bazată pe formă a alimentelor sau scanarea alimentelor de pe bon. Pe lângă numele și a datei de expirare a alimentelor se mai poate stoca și cantitatea acestora, împreună cu valorile nutriționale specifice fiecărui aliment în parte. Luând în vedere toate cele scrise mai sus, toate sarcinile stabilite la începutul dezvoltării aplicației se pot considera rezolvate, iar scopul acestui proiect – a fost atins.
45 BIBLIOGRAFIE [1] Reducerea risipei alimentare: răspunsul UE la o provocare mondială, https://ec.europa.eu/commission/presscorner/detail/ro/MEMO_16_3989, Consultat la 18.05.2020 [2] Sharma, Chetan; Nakamura, Yasuhisa (2003-11-20). Wireless Data Services: Technologies, Business Models and Global Markets. Cambridge University Press. p. 194. ISBN 978-0-521-82843-7. [3] Symbian, https://en.wikipedia.org/wiki/Symbian, Consultat la 23.05.2020 [4] Symbian Operating System, Now Open Source and Free, https://www.wired.com/2010/02/symbian-operating-system-now-open-source-and-free/, Consultat la 25.05.2020 [5] iPhone News – Newsroom Archive, https://www.apple.com/newsroom/archive/iphone/, Consultat la 25.05.2020 [6] Live from Apple's iPhone SDK press conference, https://www.engadget.com/2008-03-06-live-from-apples-iphone-press-conference.html, Consultat la 25.05.2020 [7] Android Market: Now available for users, https://www.apple.com/newsroom/archive/iphone/, Consultat 27.05.2020 [8] Microsoft’s universal app store for Windows 10 goes live on the web, https://mspoweruser.com/microsofts-universal-app-store-goes-live-web/, Consultat la 28.05.2020 [9] Chapter 1. What Is React Native?, https://www.oreilly.com/library/view/learning-react-native/9781491929049/ch01.html, Consultat la 01.06.2020 [10] NET Alternative in Transition, http://www.informationweek.com/news/development/architecture-design/229700276, Consultat la 05.06.2020 [11] David Flanagan: JavaScript: The Definitive Guide, O'Reilly Media, Inc., 2011 [12] React: Making faster, smoother UIs for data-driven Web apps, https://www.infoworld.com/article/2608181/react–making-faster–smoother-uis-for-data-driven-web-apps.html, Consultat la 10.06.2020 [13] Introducing JSX, https://reactjs.org/docs/introducing-jsx.html, Consultat la 15.06.2020 [14] Layout with Flexbox , https://reactnative.dev/docs/flexbox, Consultat la 20.06.2020 [15] Firebase Documentation, https://firebase.google.com/docs, Consultat la 25.06.2020 [16] Firebase Authentication Documentation, https://firebase.google.com/docs/auth, Consultat 25.06.2020 [17] Firebase Cloud Functions Documentation, https://firebase.google.com/docs/functions, Consultat la 30.06.2020
46 [18] The Z Shell Manual: http://zsh.sourceforge.net/Doc/Release/Introduction.html, Consultat la 01.07.2020
Copyright Notice
© Licențiada.org respectă drepturile de proprietate intelectuală și așteaptă ca toți utilizatorii să facă același lucru. Dacă consideri că un conținut de pe site încalcă drepturile tale de autor, te rugăm să trimiți o notificare DMCA.
Acest articol: Finalizare Batîr P Ion 4c [618130] (ID: 618130)
Dacă considerați că acest conținut vă încalcă drepturile de autor, vă rugăm să depuneți o cerere pe pagina noastră Copyright Takedown.
