Microsoft Word – 5.Teza_de_licenta.docx [303088]

Curpins

Introducere ………………………………………………………………………………………………………. 10 1 Analiza domeniului de studiu ………………………………………………………………………….. 11

1.1 Argumentarea temei …………………………………………………………………………………….. 12

1.2 Părțile implicate în dezvoltarea platformei de închiriere a automobilelor ……… 12

1.3 Definiții și prescurtări utilizate în document …………………………………………………. 13

1.4 Compararea cu sisteme deja existente …………………………………………………………… 13

1.4.1 Sistemul ”joyrent app” ……………………………………………………………………………… 14

1.4.2 Sistemul ”Europcar – Car Rental App” ……………………………………………………… 15

1.4.3 Sistemul ”Drivy – peer-to-peer car rental” …………………………………………………. 16

1.4.4 Sistemul ”Kwikcar – On Demand Car Rental” …………………………………………… 17 1.4.5 Sistemul ”Turo – Rent Better Cars” …………………………………………………………… 18 2 Modelarea și proiectarea sistemului informatic ……………………………………………….. 19

2.1 Proiectarea sistemului ………………………………………………………………………………….. 21

2.2.1 Imaginea generală asupra sistemului …………………………………………………………. 22

2.2.2 Descrierea scenariilor de utilizare a aplicației …………………………………………….. 25

2.2.3 Fluxurile de mesaje și legăturile dintre componentele sistemului ………………… 27

2.2.4 Stările de tranzacție a sistemului ……………………………………………………………….. 29 2.2.5 Modelarea vizuală a fluxurilor …………………………………………………………………… 31

2.2.6 Descrierea structurii statice a sistemului ……………………………………………………. 33 2.2.7 Relațiile de dependență între componentele sistemului ……………………………….. 36

Realizarea sistemului ……………………………………………………………………………………… 38

3.1 [anonimizat]-Controller(MVC) …………………………………….. 40 3.2 Descrierea la nivel de cod pe module …………………………………………………………….. 41 4 Documentarea produsului realizat ………………………………………………………………….. 63 5 Evaluarea economică a proiectului ………………………………………………………………….. 68

5.1 Planul calendaristic ……………………………………………………………………………………… 69 5.2 Analiza SWOT …………………………………………………………………………………………….. 71

Calculul indicilor economici …………………………………………………………………………. 72

Consumuri indirecte …………………………………………………………………………………….. 75

Uzura mijloacelor fixe și amortizarea activelor nemateriale pe termen lung ….. 75

Costul de producție ……………………………………………………………………………………… 76

Concluzii …………………………………………………………………………………………………………… 77 Bibliografie ……………………………………………………………………………………………………….. 78

Anexa A ……………………………………………………………………………………………………………. 79

Anexa B ……………………………………………………………………………………………………………. 84 Introducere

În zilele de astăzi am ajuns să trăim într-o lume în care mereu suntem în mișcare, dorim să călătorim fie peste hotare, fie că în interiorul țării, fie că este o călătorie de bussiness, sau doar o simplă plimbare, dar mereu avem nevoia de a ajunge sigur și rapid. Toate acestea fiind posibile cu ajutorul automobilului în majoritatea cazurilor, fie automobilul personal/al familiei/al prietenilor sau în cazul când nu avem posibilitatea sau necesitatea de a procura un automobil – unul închiriat. Fiindcă piața automobilelor este întro dezvoltare rapidă, pe zi ce trece apar tot mai multe modele noi de automobile, cu diferite specificații, astfel serviciile de chirie a automobilelor s-au răspândit foarte mult în ultimele decenii, astfel încât să ofere în chirie automobile de diferite categorii, în dependență de preț, comfort si clasă.

Fiecare companie ce oferă servicii de chirie au un sistem personalizat, un site web sau chiar și o aplicație mobilă pentru smartphone, ce permite utilizatorului să vadă ofertele companiei și detaliile automobilului precum ar fi denumirea, tipul, clasa, prețul automobilului, ba chiar și posibilitate de a depune o cerere online de chirie.

Prin implementarea acestei platforme atât clienții vor putea beneficia în urma acesteia, astfel încât compania își încarcă detele despre mașinile disponibile, iar clienții vor putea ușor să acceseze cu ajutorul aplicației mobile iOS sau Android automobilele deja disponibile, astfel ușurând și economisind timpul utilizatorului în căutarea unui automobil.

Beneficiile pentru companiile ce utilizează această platformă sunt că fiecare companie își poate gestiona propriile mașini, și plata pentru chirie se efectuează direct către companie. Iar benefiicile pentru un client sunt că la accesarea platformei, el primește rezultatele cu mașini adăugate recent, fie sortate după preț crescător, fie descrescător. Utilizatorul poate accesa detaliile unei mașini, dar și localizarea acesteia pe hartă, și detaliile despre compania ce îi oferă acest serviciu de chirie. Astfel fiecare companie are un rating anumit, în dependență de rating-ul oferit de utilizatori și datele de contact ale acesteia.

Motivul alegerii temei date constă în mulțimea de aplicații sau website-uri de la diferite companii pentru închiriere auto, ceea ce este un neajuns pentru utilizatori, astfel fiind nevoiți să piardă mai mult timp pentru căutarea unei oferte convenabile în toate companiile disponibile ceea ce îi ia unui utilizator mult mai mult timp pentru căutare, neavând posibilitatea de a analiza întreaga piață de închiriere auto printr-o singură platformă care unește toate companiile la un loc, unde sunt înregistrate automobilele acestora și utilizatorul deja să poată căuta mult mai simplu printre ofertele disponibile și pentru a o alege pe cea mai convenabilă.

Această temă nu este una nouă, ea fiind întîlnită pe magazinele de aplicații Google Play și AppStore, dar aplicațiile ce sunt acolo nu sunt disponibile pentru toate țările, ele fiind disponibile pentru țările mult mai puternic dezvoltate, cum ar fi SUA, Canada, Marea Britanie; ele fiind deja platforme existente ce grupează companiile într-un singur loc și utilizatorii deja pot accesa o singură platformă nu fiecare companie, pe când în țările cu o dezvoltare mai slabă – nu sunt disponibile aceste aplicații, ori nu este posibilitatea de a te înregistra pentru a fi partener a acestei platforme fiindcă nu faci parte dintr-un grup anumit de țări.

1 Analiza domeniului de studiu

În zilele de azi sistemele de chirie sunt răspândite pe larg, iar companiile prestează diferite servicii de chirie, precum ar fi imobiliare, automobile, biciclete, haine, echipamente foto-video, etc. Astfel clienții apelează la serviciul necesar, spre exemplu servicii de chirie a automobilelor, și preiau pe o anumită perioadă de timp un anumit automobil la un preț avantajos, fără a avea nevoia de a procura unul, economisind astfel și timp și bani.

De obicei serviciile de chirie a automobilelor sunt oferite persoanelor care dețin un automobil(sau cel puțin carnet de conducere) dar automobilul lor este inaccesibil, fie că este deteriorat sau distrus în urma unui accident și se află la un service auto, fie persoanele sunt într-o călătorie peste hotarele țării în care locuiesc și au nevoie de un mijloc de transport sigur și rapid. Astfel companiile de chirie a automobilelor sunt cel mai des plasate în aeroporturi sau în locații des populate de turiști sau în regiuni ușor accesibile de oricine, expunându-și automobilele disponibile, iar fiindcă automobile în zilele de astăzi sunt de diferite tipuri și dimensiuni, și companiile ce oferă aceste servicii trebuie să posede aceste tipuri de automobile pentru a satisface dorințele clientului [1].

Importanța domeniului ales

Deoarece suntem în timpurile în care suntem legați de tehnologiile informaționale, și acestea ne înconjoară la orice pas, astfel trăim într-o lume în care nu cred că ar putea supraviețui omenirea fără acestea, ele fiind deja în casele noastre, în mașini, pe străzi, etc. Iar noi fiind obișnuiți să călătorim cu mașina, aceasta fiind cel mai rapid și eficient mijloc de transport, dar nu orice persoană își poate permite să- și cumpere o mașină am decis să implementez o platformă pentru închirieri auto.

Fiindcă mediul online se dezvoltă cu o viteză enormă, și practic majoritatea persoanelor au acces la internet și știu să se folosească de acesta pe scară largă este un plus enorm în dezvoltarea omenirii. Cu dezvoltarea internetului s-au dezvoltat și calculatoarele, ele devenind tot mai mici și mai mici, astfel încât am ajuns ca fiecare să aibă în buzunar un smartphone și acces la internet. Iar aceste dispozitive nu oferă doar navigare pe internet dar și o utilizare largă a diferitor aplicații.

Dat fiind toate acestea, platforma online de chirie a automobilelor va cuprinde și ea aplicații mobile pe dispozitivele ce rulează sistemele de operare Android sau iOS, acestea fiind cele mai populare sisteme de operare pe dispozitivele inteligente. Astel în magazin fiind aplicația dată, utilizatorul poate să descarce aplicația pe dispozitiv și deja direct din aplicație să caute și închirieze automobilul necesar mult mai simplu.

Scopul implementării

Scopul acestei platforme este de a eficientiza munca utilizatorului în cadrul căutării unui automobil pentru chirie, astfel utilizatorul poate să caute un automobil direct pe platforma dată unde sunt înregistrate mai multe companii ce oferă aceste servicii, expunîndu-și automobilele direct pe platformă. În acest mod utilizatorul nu trebuie să caute fiecare companie în parte și să caute automobilele ce le oferă, astfel pierzând mai mult timp pentru căturări și comapniile pierzând banii din cauza aceasta, iar dacă această platforma ar uni companiile, utilizatorii în urma căutării poate vizulaiza aceeași mașină, dar oferită de mai multe companii și astfel poate alege oferta cea mai convenabilă. În acest mod se dezvoltă și concurența pe pață între companii, fiecare încercând să ofere cele mai bune prețuri si servicii calitative pentru a atrage clienții.

1.1 Argumentarea temei

Proiectarea și dezvoltarea unei platforme pentru închiriere auto a fost aleasă spre realizare pentru a crea un sistem universal și o bază de date comună pentru mai multe companii de chirie auto dintr-o anumită regine. Astfel clienții avînd la dispoziție dispozitivele sale inteligente să poată accesa cu ușurință platforma dată. Astfel această platformă permite următoarele funcții:

permite utilizatorilor aplicațiilor mobile pe platformele iOS și Android o navigare ușoară, accesînd aceleași mașini de pe orice dispozitiv;

permite utilizatorilor să caute un anumit automobil, să observe toate ofertele de la diferite companii;

permite utilizatorilor să închirieze direct un automobil și să efectueze plata utilizând metodele de plată online. Astfel utilizatorul prin completarea unui formular special are posibilitatea de a achita cu ajutorul sistemului de plăți electronice PayPal;

permite utilizatorilor aplicației să vadă informații detaliate despre companie, precum ar fi orele de lucru, datele de contact , rating-ul și comentariile utilizatorilor despre companie, dar și locația acesteia pe hartă și lista tuturor automobilelor oferite de aceasta.

Acestea ar fi cerințele de bază pentru aplicațiile mobile ale platformei, ce face parte dintr-un sistem complex, dar simplu de utilizat, intuitiv și având la dispoziție toate funcțiile necesare pentru a simtplifica procesul de închiriere a unui automobil și achitarea pentru chirie într-un mod sigur si rapid.

Scopul acestei platforme este de a eficientiza căutarea unui automobil de închiriat, oferind utilizatorului doar automobilele de la companiile verificate ce au desigur actele în regula, și nu pot fi anumite persoane care să obțină fraudulos bani pe seama clienților. Astfel platforma dată sporește siguranța clientului și oferă acestuia doar servicii de calitate înaltă la prețuri avantajoase pentru fiecare buzunar, toate acestea fiind disponibile într-o singură aplicație mobilă(iOS sau Android).

1.2 Părțile implicate în dezvoltarea platformei de închiriere a automobilelor

Părțile care sunt interesate sau implicate în dezvoltarea platformei de închiriere a automobilelor sunt:

utilizatorii – sunt acele persoane ce accesează aplicația mobilă pe un dispozitiv mobil și accesează platforma dată în scopul de a găsi și închiria un automobil anumit pentru a-și satisface nevoile personale sau de business;

companiile – sunt acele companii ce sunt deja înregistrate pe platforma dată și prestează servicii de chirie a automobilelor în diferite regiuni, ce au un anumit număr de automobile disponibile pentru chirie;

administratorul – sunt anumite persoane ce au grijă de adăugarea și verificarea companiilor și automobilelor pe platformă pentru a evita includerea pe platformă a unor companii ce au scopuri frauduloase sau a unor automobile deteriorate ce nu sunt sigure pentru a asigura securitatea în trafic a utilizatorilor.

1.3 Definiții și prescurtări utilizate în document

În cadrul documentului sunt utilizate anumite prescurtări ai unor termeni ce sunt explicate în tabelul 1.1.

Tabelul 1.1 – Prescurtările utilizate în document

Pentru a exemplifica și defini anumite noțiuni din cadrul documentului, aceste sunt explicate în tabelul 1.2.

Tabelul 1.2 – Noțiunile utilizate în document

1.4 Compararea cu sisteme deja existente

Studiind piața aplicațiilor ce oferă servicii de chirie auto, sa observat că sunt o mulțime de aplicații asemănătoare cu platforma GCR, dar în urma cercetării nu s-au dovedit a fi destul de bune și eficiente precum aceasta. Fiecare sistem informațional era diferit, având funcționalitățile sare specifice. În schimb platforma GulfCars combină cerințele necesare și simplifică procesul de închiriere a unui automobil.

1.4.1 Sistemul ”joyrent app”

Un sistem asemănător este joyrent app, care este o aplicație disponibilă doar pe dispozitivele Android. Acest sistem este destinat pentru o companie ”joyrent” care deține anumite automobile destinate chiriei. În figura 1.1 este prezetntată aplicația ”joyrent”.

Din imagini se poate observa că aplicația are un meniu ce îi oferă utilizatorului să broneze un automobil, introducând locația necesară, apoi să completeze formularul ce îi va permite ulterior să preia automobilul dorit. O altă opțiune este să caute automobilul după locație, astfel fiind afișate automobilele disponibile în apropierea sa. Pentru mai multe detalii despre companie, și ofertele acesteia utilizatorul poate accesa website-ul direct din aplicație și să-și continuie navigarea direct pe pagina web a aplicației. Iar pentru a lua legătura direct cu serviciul de clienți, utilizatorul poate apela direct din aplicație acest serviciu.

Asemănări dintre ”joyrent app” și platforma GCR:

amble platforme permit bronarea unui automobil pentru o anumită perioadă de timp care poate fi aleasă din timp;

ambele aplicații pot prelua legătura direct cu compania ce oferă aceste servicii de chirie auto;

ambele aplicații permit vizualizarea automobilelor disponibile pentru chirie.

Deosebiri dintre ”joyrent app” și platforma GCR:

aplicația joyrent app permite utilizatorului să vadă toate automobilele disponibile pentru chirie pe hartă, pe când platofrma GCR are posibilitatea de a afișa pe hartă locația unui singur automobil selectat;

platforma GCR permite plata online pentru chiria unui automobil;

platforma GCR permite vizualizarea datelor despre o anumită companie, precum ar fi orele de lucru, datele de contact și locația sediului acesteia pe harta;

platforma GCR presupune afișarea automobilelor de un anumit tip de la mai multe companii ce oferă servicii de chirie, precum și afișarea tuturor automobilelor oferite de către aceasta.

.2 Sistemul ”Europcar – Car Rental App”

Europcar este o companie din europa care are peste 5000 de filiale în 150 de țări ale lumii, astfel ea oferind posibilitatea de a închiria cu ușurință diferite automobile în diferite țări la un preț accesibil. Iar rezervarea acestora fiind făcută direct din aplicație și confirmată prin email. Sistemul Europcar dispune de mai multe tipuri de automobile, în dependență de comfort, siguranță și puterea acestuia, și la fel oferind posibilitatea rezervării acestuia utilizând aplicația mobilă fie pe dispozitivele Android sau iOS. În figura 1.2 se poate observa aplicația pe dispozitivele Android.

Din imagini se poate observa că această aplicație dispune de o listă de automobile care sunt disponibile pentru chirie, fie că sunt oferite aceste mașini într-o anumită locație introdusă sau detectată de sistemul gps al telefonului. Pentru utilizarea acestei aplicații utilizatorul trebuie să se înregistreze și să se autentifice ca să poate brona automobile.

Asemănări dintre ”Europcar” și platforma GCR:

ambele sisteme oferă o listă de mașini în dependență de regiunea selectată;

ambele aplicații oferă posibilitatea de a prelua legătura cu compania ce oferă automobilul în chirie;

ambele aplicații permit bronarea automobilului pe o anumită perioadă de timp.

Deosebiri dintre ”Europcar” și platforma GCR:

aplicația Europcar permite utilizatorului să detecteze locația sa și să-i ofere un număr de automobile disponibile în împrejurimea sa, fără ca utilizatorul să introducă anumite date despre locația sa;

platforma GCR permite diferitor companii ce sunt accepate să poată să-și plaseze automobilele direct pe platformă;

platforma GCR este capabilă de a accepta plata online la bronarea unui automobil, ceea ce permite încredere ca acesta nu va fi dat în chirie înainteea clientului ce la bronta;

platforma GCR permite vizualizarea locației automobilului pe hartă, ceea ce este mult mai convenabil pentru client decât o simplă adresă.

.3 Sistemul ”Drivy – peer-to-peer car rental”

Un alt sistem asemănător cu platforma GCR este ”Drivy”. Acest sistem permite oamenilor de rînd să-și plaseze mașinile personale pe platformă, și astfel să le ofere în chirie la un preț mult mai avantajos față de cel oferit de companiile specializate. Dar astfel de platforme nu exclud fraudele care pot fi efectuate cu ușurință de către persoanele care oferă în chirie automobilul. Sistemul dat este unul destul de bun în practică, oferind utilizatorilor Marii Britanii posibilitatea de a închiria un automobil la prețuri foarte avantajoase, aplicațiia fiind disponibilă atât pe dispozitivele iOS și Android, reprezentarea acestuia fiind arătată în figura 1.3.

Aplicația dată necesită înregistrarea/logarea în sistem cu ajutorul unui cont sau cu ajutorul Facebook-ului. Dupa autentificarea reușită apare fereasta de căutare a automobilelor dupa locația introdusă, data închirierii și data returnării, astfel primim rezultatele de la diferiți utilizatori, cu locația acestora și datele necesare de contact pentru a închiria automobilul dat.

Asemănări dintre ”Drivy” și platforma GCR:

aplicația Drivy oferă detaliile mai multor utilizatori ce oferă în chirie automobilele lor, pe când platforma GCR oferă astfel de date doar că de la companile aprobate pentru a oferi în chirie automobilele lor;

aplicația Drivy, la fel ca și platforma GCR oferă locația automobilului selectat pe hartă, detaliile despre proprietar, și despre automobil;

aplicația Drivy oferă proprietarilor de automobile un rating, asemănător cu platforma GCR ce oferă un rating companiilor, la fel acesta fiind oferit de utilizatorii aplicației;

aplicația Drivy la fel ca și platforma GCR dispune de un sistem de paltă online sigur si comod pentru orice utilziator.

Deosebirile dintre ”Drivy” și platforma GCR:

aplicația Drivy lucrează direct cu utilizatorii deja înregistrați în sistem și ce își oferă automobilele lor în chirie, pe cînd platforma GCR oferă o siguranță mai sporită în includerea comapniilor în sistem, ceea ce oferă o siguranță mult mai mare clienților platformei. .4 Sistemul ”Kwikcar – On Demand Car Rental”

Un alt sistem pentru chiria automobilelor este Kwikcar, care este asemănător cu platforma GCR, dar și cu aplicația Drivy, deoarece acesta oferă servicii de închiriere oferite de anumite persoane, nu de companii, și la fel nu pot fi excluse fraudele în acest caz, ceea ce nu oferă utilizatorului siguranța că totul va fi bine. Un ansamblu general al aplicației

Aplicația dată la fel ca si Drivy necesită autentificarea, și permite autentificarea cu Facebook. Dupa autentificare, aici deja este alt stil de căutare a automobilelor, acestae fiind plasate pe o hartă, ce afișează automobilele din apropierea utilizatorului, însă acesta poate selecta din meniu să caute un automobil în altă locație, dar la fel sunt afișate automobilele pe hartă, ceea ce nu este chiar comod în cazul când sunt o mulțime de automobile într-un anumit loc.

Asemănări între aplicația ”Kwikcar” și platforma GCR:

aplicația Kwikcar oferă toate detaliile necesare despre automobil, precum ar fi prețul chiriei, starea acestuia, specificațiile tehnice, detaliile utilizatorului ce în oferă în chirie, la fel ca și platforma GCR.

Deosebiri dintre aplicația ”Kwikcar” și platforma GCR:

aplicația Kwikcar utilizează harta pentru a afișa automobilele din împrejurime;

aplicația Kwikcar oferă un search mult mai detaliat din punct de vedere a căutării unui automobil, oferind posibilitatea de a selecta mai multe opțiuni, precum ar fi modelul automobilului, tipul caroseriei, tipul transmisiei;

platforma GCR folosește un sistem de plată online, ce asigură utilizatorului siguranță în transferul banilor;

platforma GCR lucrează cu companii care au trecut aprobarea administratorului și nu au intenții frauduloase;

platforma GCR folosește un sistem de notare a companiilor, ce oferă un rating utilizatorilor ce doresc să închirieze un automobil de la compania dată.

.5 Sistemul ”Turo – Rent Better Cars”

Un sistem asemănător cu platforma GCR este Turo, acest sistem cuprinde aplicații mobile pe platforma iOS și Android. Turo este foarte asemănător cu sistemul GCR din punct de vedere funcțional. Doar că acest sistem este disponibil doar în Statele Unite ale Americii, Canada și Marea Britanie. Turo cuprinde mai multe companii care au dorit să facă parte din această platformă și oferă servicii de chirie auto. În figura 1.5 este afișată aplicația Turo ce

Această aplicație include o pagină de logare, ce la fel permite înregistrarea cu Facebook, după care utilizatorul este rugat să aleagă locația de căutare a automobilelor. Pe pagina principală sunt afișate cele mai întrebate și căutate automobile, cu o bară de căutare ce îi permite utilizatorului să caute un anumit tip de automobil. Utilizatorul are posibilitatea de a căuta automobilele sau de a le vizualiza pe hartă, împreună cu locația acestora.

Asemănări între aplicația ”Turo” și platforma GCR :

ambele platforme presupun căutarea unui tip de automobile cu ajutorul barei de căutare, și afișarea automobileleor de la diferite companii;

ambele platforme oferă posibilitatea de a rezerva online un automobil și de a efectua plata cu ajutorul sistemului de plată online;

ambele platforme oferă detalii despre automobilul însăși, detalii despre companii și localizarea acestora pe hartă;

ambele platforme oferă legătură cu compania ce prestează aceste servicii de chirie a automobilelor;

ambele platforme oferă posibilitatea utilizatorilor de a oferi un rating companiilor de chirie.

Deosebirile dintre aplicația ”Turo” și platforma GCR:

aplicația Turo este disponibilă doar în anumite țări: SUA, Canada, Marea Britanie;

aplicația Turo are posibilitatea de a vizualiza automobilele din apropiere direct pe hartă.

2 Modelarea și proiectarea sistemului informatic

În cadrul implementării platformei GCR se urmărește crearea unui sistem informațional complex simplu de utilizat, intuitiv și având la dispoziție toate funcțiile necesare pentru a simplifica căutarea unui automobil, închirierea acestuia, efectuarea transferului printr-o metodăde plată sigură și rapidă. Un sistem simplu de utilizat este un avantaj pentru platformă deoarece utilizatorii nu trebuie să se complice în înțelegerea sistemului și utilizarea acestuia.

Scopul lucrării

Realizarea modelelor proceselor de bussiness al sistemului informațional – platformă folosită pentru închirieri auto.

Denumirea completă a sistemului și abrevierea:

Denumirea completă a sistemului: Gulfcars – Platformă de închiriere auto

Denumirea prescurtată: GCR

Denumirea întreprinderii beneficiarului și rechizitele lui: Beneficiarul sistemului: LEBO Projects S.R.L.

Adresa beneficiarului: MD-2001, bul. Iuri Gagarin 14, of. 44

Termenii planificați de elaborare și implementarea sistemului informațional:

Termenii planificați pentru elaborarea sistemului informațional – 25/09/2017

Termenii planificați pentru implementarea sistemului informațional – 10/05/2018

Informații despre condițiile condițiie de exploatare și caracteristicile sistemului. Elaborarea specificațiilor tehnice:

În cadrul lucrării respective este urmărit scopul de a elabora specificațiile tehnice pentru o platformă de închiriere a automobilelor. Platoforma constă în crearea aplicațiilor Android și iOS.

Mai jos sunt prezentate cerințele pentru a rula aplicația pe dispoizitivele respective:

dispoizitiv ce rulează Android 4.4 sau mai recent, sau un dispozitiv Apple ce rulează versiunea iOS 10 sau mai recentă;

conexiune la internet prin WiFi sau conexiune celulară pentru sincronizarea cu serverul.

Scopul sistemului informațional:

Platforma dată este destinată pentru utilizatorii care doresc să caute un automobil pentru închiriere conform preferințelor sale. Astfel utilizatorul are posibilitatea de a căuta mașinile în toate companiile înregistrate pe platformă și să aleagă oferta cea mai convenabilă pentru el.

Funcțiile sistemului informațional:

Pentru îndeplinirea scopurilor de mai sus platforma trebuie să realizeze următoarele cerințe:

aplicația are numele ”Gulfcars”;

limba utilizată este Engleza;

iconița aplicației este logo-ul companiei Gulfcars.

Pagina principală:

la accesarea aplicației se deschide interfața grafică ce afișează lista de mașini recent apărute;

în bara de sus va fi de sortare a mașinilor, care va cuprinde sortarea dupa preț ascendent, descendent și mașinile recent apărute.

în bara de sus va fi plasat butonul de căutare a mașinii după cuvinte cheie, iar la căutarea unei mașini specifice se vor afișa rezultatele căutării;

fiecare element din lista va arăta astfel: imaginea mașinii, în colțul stânga va fi afișat prețul mașinii, iar în partea dreaptă jos va fi afișată denumirea acesteia.

Pagina de detalii a mașinii:

pagina dată va fi compusă din mai multe compartimente: imaginile mașinii, datele de contact, descrierea acesteia, detaliile, dealer-ul și locația mașinii;

imaginile mașinii vor fi sub forma unui slideshow, care se vor schimba automat la fiecare 5 secunde;

pentru datele de contact se vor folosi 3 butoane care vor efectua acțiunile de apel către dealer, trimiterea unui mesaj sau a unui e-mail către dealer;

la descrierea mașinii se va afișa un text de maxim 250 caractere, care va include scurtă descriere a mașinii;

detaliile mașinii vor include specificațiile tehnice ale acesteia;

câmpul unde se va afișa dealer-ul mașinii va cuprinde logo-ul acestuia și denumirea sa, dar va fi și un buton care va redirecționa utilizatorul spre pagina dealer-ului;

în partea de jos a paginii va fi afișată harta în Google Maps unde este localizată mașina;

în bara de sus a paginii în partea dreaptă va fi un buton de închiriere a mașinii care va face redirect la pagina de efectuare a tranzacției.

Pagina de detalii a dealer-ului:

pagina de detalii a dealer-ului va cuprinde la fel mai multe compartimente: logo-ul dealer-ului, detaliile despre acesta precum ar fi orele de lucru și adresa, butoanele de contact direct cu dealer-ul, rating-ul dealer-ului, și localizarea oficiului acestuia pe hartă;

logo-ul dealer-ului va fi afișat în primul câmp, fiind urmat de denumirea sa și orele de lucru;

adresa va avea un cîmp aparte, unde va fi afișată adresa oficiului;

datele de contact vor fi 3 butoane de acțiune precum ar fi apelarea dealer-ului, trimiterea unui mesaj sau unui e-mail;

rating-ul dealer-ului va fi poziționat într-un câmp aparte, și va fi preluat de pe ratingul de la Google. Astfel dacă nu există nici un rating, acest cîmp nu va fi afișat, iar în caz contrar se va afișa ratingul general și unul din mesajele recente;

harta va fi poziționată în partea de jos a paginii și va afișa locația oficiului direct pe hartă.

Pagina de detalii a rating-ului a unui dealer:

pagina va conține ultimele 5 rating-uri ale utilizatorilor, cu mesajele acestora și nota lor pentru dealer-ul curent;

în bara de sus în partea dreaptă va fi poziționat un buton care va trimite utilizatorul pentru a adăuga un nou review despre compania curentă.

2.1 Proiectarea sistemului

Modelarea sistemului dat a fost elaborată în istrumentul Enterprise Architect. S-a ales instrumentul dat, deoarece este simplu, ușor de utilizat și comunicabil cu utilizatorul.

Enterprise Architect este un software de tip CASE pentru design-ul și construcția sistemelor software, bazat pe UML. Acest pachet prevede modelarea completă a ciclului de viață pentru afaceri și sisteme IT; software și ingineria sistemelor și integrarea dezvoltării în timp real [3].

Integrând capacitățile de gestionare a cerințelor, Enterprise Architect ajută la urmărirea specificațiilor la nivel înalt pentru analiza, proiectarea, implementarea, testarea și întreținerea modelelor folosind UML.

Enterprise Architect este un instrument grafic, proiectat pentru a ajuta echipele, construind sisteme robuste și întreținute. Utilizând calitatea înaltă, integrarea raportării și documentării poate oferi o viziune împărtășită cu ușurință și precizie.

UML (Unified Modeling Language) este un instrument standard pentru crearea de "diagrame" software. Cu ajutorul UML pot fi vizualizate, specificate, construite și documentate artefactele de sisteme software.

Modelarea UML este potrivită pentru toate sistemele, de la sistemele de informare la aplicatii bazate pe web și sisteme în timp real chiar încorporate. Acesta este un limbaj foarte expresiv, care permite sistemului să ia în considerare toate punctele de vedere legate de dezvoltarea și implementarea ulterioară[4].

Pentru dezvoltarea temei este necesar de implementat o platformă care să ușureze activitatea utilizatorului în căutarea unui automobil pentru chirie. Platforma dată trebuie să permită utilizatorului să caute, analizeze rezultatele primite, și să poate efectua o comandă doar din câteva mișcări simple și intuitive.

Platforma dată pune la dispozitila utilizatorului toate automobilele disponibile, de la diferite companii, ceea ce presupune o concurență între acestea pentru a oferi un serviciu cât mai performant la un preț accesibil. Iar după închirierea unui automobil de la o anumită companie, să se efectueze plata și toate cele necesare pentru a exclude rutina și documentele inutile pentru chirie, lăsând doar cele mai importante.

Utilizatorii ce vor accesa aplicațiile mobile sunt clienții ce folosesc fie un dispozitiv inteligent ce rulează sistemul de operare iOS, fie sistemul de operare Android, acestea fiind cele mai populare pe piață.

2.2.1 Imaginea generală asupra sistemului

O diagramă a cazurilor de utilizare reprezintă o colecție de cazuri de utilizare și actori care oferă o descriere generală a modului în care va fi utilizat sistemul, arată cum interacționează sistemul cu unul sau mai mulți actori, furnizează o privire de ansamblu a funcționalităților ce se doresc a fi oferite de sistem și asigură faptul că sistemul va produce ceea ce sa dorit[5].

În figura 2.1 este reprezentată diagrama generală a cazurilor de utilizare a aplicației și posibilitățile pe care le pot efectua utilizatorii.

Figura 2.1 – Imaginea generală a sistemului

Din cele menționate anterior, se poate concluziona că utilizatorii finali ai sistemului informațional dezvoltat sînt utilizatorii care descarcă aplicația de pe AppStore sau Google Play. Astfel fiecare utilizator poate efectua diferite acțiuni precum ar fi să vizualizeze automobilele recent apărute, să caute anumite automobile, să vadă detaliile și notele unei companii, sau chiar să achite online plata pentru chirie.

În diagrama vizualizării detaliilor despre mașină, utilizatorul are posibilitatea de a efectua următoarele acăiuni precum ar fi luarea legăturii cu compania ce oferă acest automobil în chirie și această legătură poate fi atât prin intermediul apelului telefonic, cât și prin mesaj sau email. Alte acțiuni pe care utilizatorul le paote face este să vizualizeze detaliile automobilului, datele tehnice, imaginile și locația acestuia. Toate acestea fiind afișate în Figura 2.2:

Figura 2.2 – Imaginea generală a detaliilor despre mașină

Diagrama din Figura 2.3 include detaliile dealer-ului și datele de contact a acestuia. Aici sunt descrise detaliile disponibile pe pagina dată.

Figura 2.3 – Imaginea generală a paginii detaliilor despre dealer

La afișarea detaliilor despre dealer, utilizatorului i se afișează detaliile acestuia precum ar fi orele de lucru, adresa acestuia, ratingul care a fost oferit de alți utilizatori și butoanele de contactare a acestuia.

În figura 2.4 sunt afișate metodele de sortare disponibile pentru aplicațiile mobile.

Figura 2.4 Imaginea generală a tipurilor de sortare

Dupa diagrama dată se poate observa că sistemul dat are opțiunea de a sorta lista de automobile primite în 3 tipuri, după data de adăugare a automobilului, după preț ascendent sau descendent.

Pentru efectuarea achitării cu cardul, în diagrama 2.5 sunt afișate datele necesare pentru a fi introduse pentru achitare.

Figura 2.5 – Imaginea generală pentru achitarea online

Pentru achitarea online, sunt necesare de introdus datele personale ale utilizatorului ce include numele, prenumele, datele cardului, pentru a putea efectua transferul online sigur și fără prea multe bătăi de cap.

2.2.2 Descrierea scenariilor de utilizare a aplicației

Diagramele de secvențe descriu interacțiunile dintre două sau mai multe entități și ordinea în care mesajele sunt schimbate între acestea. Sunt folosite în special pentru a reprezenta interacțiunile dintre obiecte.

Diagramele de secvențe sunt utilizate pentru:

descrierea scenariilor de utilizare a aplicației. Pentru fiecare diagramă a cazurilor de utilizare definită în cadrul procesului de analiză se pot defini unul sau mai multe scenarii de utilizare prin care se evidențiază fluxurile de mesaje între sistem și utilizator sau intre componentele sistemului;

descrierea logicii metodelor – diagramele de secvențe pot fi folosite pentru a descrie logica de funcționare a funcțiilor sau proceselor complexe;

descrierea logicii unui serviciu sau proces – pentru a implementa o funcție complexă la nivelul sistemului este nevoie ca două sau mai multe componente să interacționeze. Diagramele de secvențe permit reprezentarea fluxurilor de mesaje între componentele sistemului, evidențiind și constrângerile temporare (ordine de execuție, durate de execuție, termene limită).

Din cele menționate anterior, se poate concluziona că utilizatorii finali ai sistemului sunt utilizatorii ce utilizează aplicația de chirie a mașinilor. În figura 2.4, figura 2.5 și figura 2.6 sunt indicate diagramele de secvență pentru utilizarea anumitor acțiuni care utilizatorii le pot efectua pentru a utiliza aplicația.

Figura 2.4 – Scenariul pentru achitarea chiriei mașinii

Pentru a închiria un automobil este necesar în primul și primul rând de accesat aplicația GCR, ce afișează lista de mașini recent apărute. Din această liste se alege un automobil dorit, care este selectat pentru a putea fi închiriat. La apăsarea butonului de închiriere apare o formă specială ce necesită a fi completată cu anumite date, pentru a confirma cererea de închiriere și a efectua transferul pentru cererea dată.

Figura 2.5 – Scenariul pentru adăugarea unui review dealer-ului

Din cele observate în figura precedentă, pentru a trimite un review către server este necesar mai întâi de a accesa o mașină anumită, apoi de selectat dealer-ul acestui autoturism, după care apare opțiunea de a adăuga un nou review pentru dealer-ul dat.

Figura 2.6 – Scenariul corespunzător procesului de vizualizare a mașinii căutate după cuvinte cheie

Diagrama precedentă reprezintă acțiunile utilizatorului în timpul căutării unui automobil utilizînd cuvintele cheie precum ar fi BMW, Audi … etc, astfel se caută în toate mașinile disponibile mașinile căutate, și se returnează rezultatele necesare, oferind posibilitatea utiliaztorului să selecteze automobilul preferat.

2.2.3 Fluxurile de mesaje și legăturile dintre componentele sistemului

Diagramele de desfășurare sunt utilizate pentru a vizualiza topologia componentelor fizice ale unui sistem în care componentele software sunt implementate. Așadar, diagramele de desfășurare sunt folosite pentru a descrie desfășurarea statica a unui sistem, și consista din noduri si relația între ele.

Numele de „desfășurare” se descrie pe sine în scopul de diagrama. Diagramele de desfășurare sunt utilizate pentru a descrie componentele hardware în care componentele software sunt vizualizate. Aceste diagrame de desfasurare și diagramele de componente sunt strâns legate.

Diagramele Componentelor sunt folosite pentru a descrie componentele, iar diagramele de desfășurare arată modul în care acestea sunt dislocate în hardware. UML este în principal destinat să se concentreze pe artefactele software ale unui sistem. Dar aceste două diagrame sunt diagrame de construcții utilizate pentru a se concentra pe componente software și componente hardware.

Deci, cele mai multe diagrame UML sunt utilizate pentru a manipula componente logice, dar diagramele de desfășurare sunt făcute ca să se concentreze asupra topologiei hardware a unui sistem. Diagramele de desfășurare sunt utilizate de către inginerii de sistem.

Scopul diagramelor de desfășurare pot fi descrise ca:

vizualizarea topologiei hardware a unui sistem;

descrie componentele hardware utilizate pentru a implementa componente software; – descrie noduri runtime de prelucrare.

În figura 2.7 se observă diagrama în care un utilizator adaugă un nou review la un anumit dealer, ceea se realizează prin aplicație și se face legătura directă cu serverul Google unde sunt păstrate aceste date despre Review-uri.

Figura 2.7 – Fluxul de mesaje corespunzător adăugării unui review

Diagrama din figura 2.8 include actorul Utilizator, care accesează aplicația și selectează mașina preferată. Astfel la selectarea acesteia se face legătura cu serverul Google pentru a utiliza Google Maps pentru afișarea locației mașinii pe hartă, ca utilizatorul să poată naviga cât mai rapid către destinație.

Figura 2.8 – Legătura dintre componentele sistemului în cadrul vizualizării hărții

Diagrama din figura 2.9 include actorul Utilizator care accesează aplicația, care la rîndul său se conectează la server pentru descărcarea datelor necesare, pe cînd serverul se conectează la baza de date pentru descărcarea datelor și afișarea acestăra pe ecranele dispozitivelor.

Figura 2.9 – Fluxul de mesaje corespunzător procesului de accesare și conectare dintre aplicație și server

2.2.4 Stările de tranzacție a sistemului

Diagrama de stare descrie procesul de modificare a starilor numai pentru o clasă, mai exact pentru obiectele clasei, adică modelează toate modificările posibile în starea unui obiect complet. Modificarea stării obiectului poate fi provocată de influența externă a altor obiecte sau de către obiectele clasei. Anume pentru a descrie relațiile obiectelor se utilizează diagrama de stare. Diagrama dată se utilizează pentru descrierea consecutivității de stări posibile și tranziții care în ansamblu caracterizează comportamentul obiectelor modelate pe parcursul ciclului său de viață. Diagrama de stare reprezintă comportamentul dinamic a entităților în baza specificației reacții lor la perceperea anumitor evenimente. Diagrama de stare grafic se reprezintă în formă de graf care reprezintă un automat. Vîrfurile sunt stări, pseudostări, Arcuri tranziții.

Automatul în UML reprezintă o formalizare pentru modelarea comportamentului elementului modelului și a sistemului întreg. În meta modelul UML, Automatul este un pachet în care sunt definite o mulțime de definiții necesare pentru reprezentarea comportamentului entităților modelate în formă de spațiu discret și cu un număr finit de stări și tranziții.

Starea în UML se subînțelege ca o metaclasă abstractă care se utilizează pentru modelarea unor situații aparte pe parcursul căreia sunt prezente executatarea mai multor condiții.

Numele stării reprezintă un aliniat de text care dezvăluie sensul stării. Se scrie cu literă majusculă. Numele trebuie să fie în formă de verb la timpul prezent sau participiu. Numele poate lipsi, și în acest caz se numește stare anonimă.

Tranziții reprezintă o relație între 2 stări consecutive indicînd faptul schimbării unei stări cu alta. Se reprezintă printr-o linie neîntreruptă cu săgeată în capăt.

Eveniment este un element independent al limbajului UML. Obțional evenimentul reprezintă specificația anumitui fapt care are atașată o locație în timp și spațiu.

Figura 2.10 – Stările corespunzătoare Paginii principale

Diagrama dată include controlorul conexiunii la internet și stările acesteia. La început se afișează pagina principală și se verifică conexiunea la internet cu serverul API. Dacă legătura cu internetul lipsește se afișează un mesaj de eroare.

Figura 2.11 – Stările corespunzătoare controllerului de căutare

Diagrama dată include controllerul Cautare a unei mașini, astfel la introducerea cuvintelor cheie are loc interogarea cu serverul și cererea datelor de pe server, la primirea răspunsului, dacă sunt mașini se afișează lista de mașini, dacă mașinile sunt lipsă sau este eroare de conexiune se afișează mesajul de eroare.

Figura 2.12 – Stările corespunzătoare Vizualizarii review-urilor

Diagrama dată include clasele de Vizualizare a dealer-ului, review-urilor și funcționalitatea de adăugare a unui review. Astfel la accesarea controllerului de afișare a detaliilor Dealerului, se verifică dacă sunt sau nu review-uri la dealer-ul dat, în cazul că acestea lipsesc se ascunde opțiunea curentă.

2.2.5 Modelarea vizuală a fluxurilor

În diagrama de activități se reflectă logica sau consecutivitatea tranzițiilor de la o acțiune la alta, totodată se evidențiază rezultatul activității. Rezultatul, la rîndul său poate duce la schimbarea stării sistemului dat sau la returnarea unei valori. Notația grafică a diagramei de activități are mult în comun cu notația diagramei de stare cu motivul că elementele principale sunt starea și tranziția. Deosebirea constă în semantica stărilor, care sunt utilizate pentru realizarea acțiunilor ei nu a activităților și în aceea că tranzițiile în diagramele de activități sunt netrighere.

Starea activității se utilizează pentru modelarea unui pas de execușie a algoritmului sau a unui flux de control. Grafic starea activităților se reprezintă prin forma unui dreptunghi laturile căruia sunt substituite cu arcuri convexe. Numele trebuie să fie unic în cadrul unei diagrame. El poate fi scris în limbajul natural, pseudocod sau intr-un limbaj de programare. Tranziția în diagrama de activități este netrigheră. Ea nu poate conține aliniate de text. Uneori este necesar de a reprezenta cel puțin 2 tranziții a unei stare activitate, însă conform definiții nu se permite și pentru acest tip de tranziții este utilizat elementului ramificator.

În figura următoare este reprezentată prima diagramă de activități care descrie activitățile utilizatorului în procesul de efectuare a unui apel la selectarea unei mașini cu care dorește să facă legătura cu dealer-ul. Utilizatorul selectînd mașina, selectează opțiunea de apelare a dealer-ului, după care este efectuat apelul către dealer.

Figura 2.13 – Fluxul de activități pentru apelarea dealerului mașinii.

Diagrama din Figura 2.14 include activitățile utilizatorului care sunt necesare pentru a fi efectuate pentru a căuta o anumită mașină după anumite cuvinte cheie. După căutarea mașinilor pe server, se afișează fie lista de mașini fie un mesaj de eroare.

Figura 2.14 – Fluxul de activități corespunzătoare procesului de căutare a unei mașini după cuvinte cheie

Diagrama de activitate corespunzătoare procedurii de afișare a reviewurilor unui dealer din Figura 2.15 reprezintă opțiunea de a afișa la ecran review-urile utilizatorilor sau de a ascunde această opțiune în caz că acestea lipsesc.

Figura 2.15 – Fluxul de activități corespunzătoare procedurii de afișare a review-urilor

2.2.6 Descrierea structurii statice a sistemului

În Figura 2.16 sunt reprezentate clasele listei cu mașini a aplicației mobile. Clasa principală este MainView, DealerCarListView, SearchView, CarDetailsView care utilizează modelul CarDetails, care la rîndul sau apelează APIClient ce descarcă datele de pe URL.

Figura 2.16 – Structura claselor și conexiunea dintre acestea pentru afișarea detaliilor unui automobil.

În figura 2.17 este prezentată diagrama de clase ce afișează pe dispozitiv toate datele ce țin de review-urile dealerului, ce include nota, mesajul și persoana ce a scris acest mesaj.

Figura 2.17 – Structura claselor și legăturile necesare pentru așiarea review-urilor.

În figura 2.18 este afișată diagrama de clase a aplicației ce răspunde de cererea, prelucrarea datelor și afișarea la ecran a datelor despre dealer-ul mașinii, aici sunt incluse anumite câmpuri, precum denumirea, logo-ul, locația, orele de lucru, numărul de contact sau email.

Figura 2.18 – Clasele necesare și legătura dintre acestea pentru afișarea unei companii.

În figura 2.19 este reprezentată diagrama de clase a aplicației unde sunt reprezentate clasele modelelor și clasele controllerelor acestora. Clasele controllerelor MainViewController, SearchViewController, DealerCarListViewController, sunt legate prin relația de compoziție cu o multiplicitate de 1 la mulți de celulele tabelelor ce populează aceste controller, aceste celule fiind legate prin relația de compoziție cu o multiplicitate 1 la 1 de modelul CarCard. Clasa controllerului ReviewsViewController este legată de celula tabelului prin relația de compoziție cu multiplicitatea 1 la mulți, deoarece tabelul cuprinde mai multe celule asemănătoare de cu review-uri, iar la rândul lor, celula este strâns legată de modelul ReviewCard prin relația de compoziție cu o multiplicitate 1 la 1. Pentru controllerul CarDetailsViewController se stabilește o relație de compoziție cu o multiplicitate 1 la 1 cu modelul CarDetails, deoarece acest controller afișează detaliile unei mașini ce le ia direct din acest model. Iar pentru controllerului DealerViewController se stabilește 2 relații de compoziție cu modelele CarDealer și BasicReviewDetails cu o multiplicitate 1 la 1 deoarece acest controller afișează detaliile unui dealer de mașini, ce sunt luate direct din modelul CarDealer, iar în cazul când sunt prezente și review-uri auspra unui dealer atunci sunt afișate si detaliile despre reviewurile acestuia.

Figura 2.19 – Clasele și legăturile dintre modele și controllere.

2.2.7 Relațiile de dependență între componentele sistemului

În diagrama din Figura 2.20 putem observa dependenț ele necesare pentru aplicația pe dispozitivele iOS, aceste dependențe, crează o legătură sau implementează o utilizare mai eficientă a resurselor dispozitivului dar și prelucrarea acestora mai rapid ăn interiorul aplicației.

Figura 2.20 – Componentele corespunzătoare dependențelor necesare pentru dispozitivele iOS.

În Figura 2.21 se pot observa dependențele necesare pentru dispozitivle Android, care la fel sunt utile în prelucrarea informației și utilizarea mai eficientă a acestora.

Figura 2.21 – Componentele corespunzătoare dependențelor necesare pentru dispozitivele Android.

Diagrama din Figura 2.22 indică structura sistemului, și cum are loc cererea API-ului de la server către aplicație. Astfel aplicația mobilă cere datele de la server, pe când acesta apelează baza de date, selectează datele necesare și le transformă în format JSON pentru a putea fi prelucrate mai ușor decît alte formate necunoscute.

Figura 2.22 – Componentele de bază în construcția API-ului.

3 Realizarea sistemului

Realizarea sistemului presupune implementarea aplicațiilor mobile pentru a ușura munca utilizatorilor, deoarece aplicațiile mobile sunt mult mai ușor înțelese de utilizatori deoarece ele oferă o experiență mult mai bună în utilizare, excluzând faptul de a accesa siteul web pentr a brona un automobil, totul fiind deja implementat în aplicție.

Pentru realizarea platformei am uitilizat 2 tipuri SO pentru aplicații mobile, Android is iOS, acestea fiind cele mai populare pe piața dispozitivelor mobile, fiecare având plusurile și minusurile sale, ceea ce nu este o problemă în realizarea platformei de chirie a automobilelor. Iar pentru aceasta se vor folosi 2 limbaje de programare Java pentru sistemul de operare Android și Swift 4 pentru sistemul de operare iOS.

Android este un SO mobil bazat pe o versiune modificată de Linux (pentru gestiunea componentelor hardware, a proceselor și a memoriei) și biblioteci Java (pentru telefonie (audio/video), conectivitate, grafică, programarea interfețelor cu utilizatorul). Este un produs open-source (putând fi dezvoltat de producătorii de dispozitive mobile cu extensii proprietare pentru a-și particulariza platforma), dezvoltat în prezent de compania Google, conceput pe ideea transformării dispozitivelor mobile în adevărate mașini de calcul.[6]

Astfel pentru dezvoltarea aplicațiilor mobile pe acest SO se folosește limbajul Java, care este unul dintre cele mai adaptate limbaje pe scară largă în cadrul corporațiilor. Java fiind un limbaj de programare obiect-orientat și puternic tipizat, independent de platformă, dinamic și distribuit, cu multiple fire de execuție, robust și sigur. Obstacolele în dezvoltarea aplicațiilor include faptul că Android nu utilizează standartele stabilite de Java, care sunt, Java SE și ME. Acestea previn compatibilitatea între aplicațiile Java pentru anumite platforme și aplicațiile Java scrise pentru platforma Android. Android doar reutilizează limbajul Java, sintaxa și semantica acestuia, dar nu utilizeaza toate liprariile șo API-urile oferite de Java SE sau ME. [7]

Ca IDE se folosește Android Studio, acesta fiidn IDE-ul oficial oferit de Google, dezvoltat special pentru dezvoltarea aplicațiilor pe platforma Android. Iar el oferă o interfață accesibilă pentru dezvoltatorii de aplicații Android, care le permite să gestioneze fișierele mult mai rapid, să aranjeze ferestrele de lucru după nevoile proprii și să testeze pe simulatoarele oferite aplicațiile dezvoltate, astfel încât programatorul să dezvolte un produs calitativ pentru orice dispozitiv ce rulează SO Android. Acest IDE mai permite și adăugarea diferitor librării(package) pentru a gestiona mai ușor cu anumite componente ale aplicației. Pentru platforma dată se vor folosi următoarele librării:

Google Maps – este o librărie ce permite încorporarea și afișarea hărților oferite de Google, plasarea diferitor puncte pe hartă și utilizarea tuturor opțiunilor oferite de Google pentru a crea o experiență cât mai plăcută în utilizarea aplicațiilor. În cazul platformei se va folosi afișarea locației automobilului sau companiei de oferă aceste servicii direct pe hartă;

CircleImageView – este o librărie ce permite transformarea unui ImageView într-o imagine rotundă oferind stil si design în aplicația Android;

Volley – este o librărie destinată lucrului cu rețeaua, și anume transmiterea și recepționarea datelor prin rețea, lucrul cu fișierele JSON. Astfel cu ajutorul acestei librării cu mult mai ușor dezvoltatorul poate prelucra traficul pe care îl primește și exclude apariția erorilor;

ViewPageIndicator – este o librărie destinată elementului ViewPager, ce afișează în partea de jos câte elemente sunt și care element este afișat, în cazul nostru care imagine este afișată.

SO de operare iOS este un sistem creat de către Apple, el fiind sistem de operare de tip Unix. Iar acest sistem este destinat pentru dispozitivele Apple, precum ar fi iPhone, iPod, iPad. Astfel prin funcționalitatea sa, iOS sa dovedit a fi unul din factorii de succes primordial al telefoanelor iPhone pe piața mondială.

Pentru dezvoltarea aplicațiilor pe acest sistem de operare se folosește limbajul de programare Swift 4, el fiind cel mai recent limbaj oferit de Apple, astfel oferind dezvoltatorilor o interfață și o structură mult mai simplă în detectarea erorilor. La fel ca și Java, Swift este un limbaj multi-paradigmă, obiect-orientat, funcțional și structurat pe blocuri. Special creat pentru a sustine dezvoltarea sistemelor iOS și OS X, Swift este un limbaj de programare compilat. Ce înseamna acest lucru? Swift înglobează elemente inspirate din multiple alte limbaje de programare, însumând doar cele mai bune caracteristici, pentru a oferi deplina lejeritate dezvoltatorilor de aplicații și programatorilor. Printre elementele limbajelor de programare din care s-au inspirat creatorii Swift se numară C, Objective-C, Rust, Python, Ruby sau Haskel.

Întreaga documentație aferentă acestui limbaj de programare este pusă la dispoziția doritorilor de către Apple. Cei interesați ar trebui să știe de asemenea că Swift rulează pe două interfețe distincte:

interfața Cocoa – destinată sistemului de operare OS X;

interfața Cocoa Touch – destinată sistemului de operare iOS [8].

Ca IDE se folosește Xcode, acesta fiind unicul IDE oferit de Apple și utilizat pentru crearea aplicațiilor în Swift, acesta include toate cele necesare pentru a crea aplicații pentru dispozitivele Apple. Xcode oferă dezvoltatorilor un flux de lucru unificat pentru proiectarea, codarea, testarea și depanarea erorilor. La fel ca și în Android Studio, Xcode oferă o mulțime de librării care simplifică munca dezvoltatorilor în timpul dezvoltării unei aplicații. Pentru aplicația pe platforma iOS se vor folosi următoarele librării(pod-uri):

Alamofire – este o librărie destinată lucrului cu rețeaua, ce cu ușurință tratează cererile din rețea;

SwiftyJSON – este o librărie ce cu ușurință prelucrează crererile primite in format JSON, și extrage datele din ele;

AlamofireImage – este o librărie pentru descărcarea asincronă a imaginilor de pe internet;

ImageSlideshow – este o librăria pentru implementarea unui slideshow cu anumite imagini, aceasta poate lucra cu AlamofireImage împreună, afișând o galerie de imagini de pe internet;

ReachabilitySwift – aceasta este o librărie predestinată verificării conexiunii la internet, în caz că există aplicația rulează normal, iar în caz contrar afișează un mesaj de eroare;

GoogleMaps – este o librărie pentru afișarea Hărților Google în aplicație, împreună cu punctele/rutele și funcționalitățile acesteia;

TBDropdownMenu – este o librărie ce creează un meniu dropdown asemănător celui de la Android;

Cosmos – este o librărie destinată afișării numărului de stele, în cazul nostru se afișează rating-ul companiilor;

PKHUD – este o librărie simple pentru afișarea unor pop-upuri animate precum ar fi cel de încărcare, ok, sau eroare.

3.1 Modelul arhitectural Model-View-Controller(MVC)

Pentru implementarea aplicației mobile se utilizează modelul arhitectural ModelView-Controller(MVC), el fiind un șablon arhitectural folosit în industria de software development. Astfel el izolează cu succes partea logică de interfața proiectului, permițând întreținerea, dezvoltarea și testarea separată a celor două părți. În figura 3.1 este prezentat grafic modelul arhitectural MVC, în care după cum se poate vedea el împarte aplicația în 3 părți principale: model, view și controller.

Modelul reprezintă partea logică a aplicației. El răspunde de acțiunile și operațiile asupra datelor, înregistrarea anumitor clase destinate pentru prelucrarea informațiilor din diverse baze de date;

View-ul reprezintă partea grafică a aplicației, astfel el se ocupă cu afișarea datelor și are grija cum vede end-userul informația, în cazul dat pe ecranul dispozitivului mobil. Odată ce datele sunt prelucrate de către controller, către view sunt trimise rezultatele, iar acesta deja le afișează utilizatorului;

Controller-ul este creierul aplicației, el este componentul ce face legătura dintre model și view, dintre acțiunile utilizatorului și deciziile aplicației însăși. Controllerul folosește datele din model pentru a le prelucra, care mai apoi tirmite informațiile noi către view pentru a fi afișate utilizatorului[9].

Figura 3.1 – Model-View-Controller

Avantajele unei aplicații bazate pe MVC:

gestionare mumt mai simplă prin divizarea acesteia în modele, controlere si viewuri;

utilizarea unui model pentru mai multe view-uri, astfel separarea acestora permite utilizarea în multiple view-uri dar păstrând acelașii model;

arhitecura permite reutilizarea codului;

simplifică controlul comportamentului modelelor;

permite adăugarea, modificarea sau chiar ștergerea interfețelor cu ușurintă.

3.2 Descrierea la nivel de cod pe module

Pentru elaborarea aplicațiiei mobile pe platforma iOS sunt utilizate storyboard-urile, ele sunt utilizate pentru crearea interfețelor aplicației și dețin o mulțime de șabloane pentru a putea crea aplicații pentru orice necesitate. Storyboard-ul permite implementarea mai multor interfețe într-un singur fișier, și crearea legăturilor dintre acestea. În figura 3.2 este prezentat storyboard-ul pentru aplicația GulfCars pe platforma iOS. În această aplicație este utilizat controllerul de navigare, el fiind un șablon ce permite navigarea cu ușurință între interfețele aplicației, oferind toate cele necesare precum ar fi tranzițiile între interfețe, legăturile între acestea, bara de acțiune și butoanele necesare pentru a naviga în acest controller de navigare. Acest controller poate fi instanțiat odată cu pornirea aplicației și el să fie prezent în toată aplicația, cum este utilizat și în cadrul aplicației GulfCars. Iar pentru adăugarea elementelor pe aceste interfețe se trag elementele necesare peste interfață, totul fiind intuitiv și ușor de implementat de către dezvoltator[10].

Storyboard-urile au fost introduse încă în iOS 5, ca o nouă funcționalitate de design a interfețelor. Astfel toate proiectele au cel puțin un storyboard care este utilizat(Main.storyboard). Astfel în interiorul acestui storyboard pot fi atâtea interfețe de câte este nevoie, iar după aceasta se pot implementa tranzițiile segue, așa numitele „segway” care reprezintă tranzițiile între controllere[11]. Punctul de start a unei tranziții poate fi acșiunea unui buton, a unei celule din tabel sau chiar a unui gest executat. Punctul de final este controllerul ce va fi afișat. Iar aceste tranziții pot fi de mai multe tipuri, chiar pot fi create și tranziții personalizate.

Figura 3.2 – Storyboard-ul aplicației GulfCars

Pentru afișarea automobilelor într-o listă folosim TableView, el reprezentând o coloană cu mai multe elemente care pot fi derulate. Astfel pentru definirea unui TabelView dinamic se folosesc celulele prototip(Prototype Cells) care la fel ca și o interfață conține anumite elemente precum ar fi text, imagini, etc. În figura 3.3 este reprezentată celula prototip pentru elementul unui automobil în lista de automobile afișată pe pagina principală. Astfel această celulă a listei conține un ImageView și două Texte care reprezintă numele automobilului și prețul acestuia.

Pentru pagina de detalii a automobiluli și a dealer-ului se folosește un TableView cu celule statice, care sunt predefinite deodată în interfață, fără utilizarea celulelor dinamice și crearea claselor separate. Aceste interfețe pot fi observate mai detaliat în figura 3.4. Astfel interfața detaliilor unui automobil este secționată în următoarele părți:

un View ce conține o prezentare de imagini a automobilului care sunt prelucrate de framework-ul ImageSlideshow, care prelucrează imaginile, le aranjează într-un slider și le interschimbă între ele automat;

3 butoane rotunde cu imagini pentru apelare, trimitere e-mail și trimitere sms;

o scurtă descriere despre automobil introdusă într-un TextView;

câteva rînduri de text ce conțin detaliile tehnice ale automobilului;

o imagine circulară și denumirea dealer-ului ce propune automobilul spre chirie;

un View ce conține o hartă pe care este plasată locația curentă a automobilului, iar harta este prelucrată de framework-ul GoogleMaps ce permite integrarea hărților google și afișarea acestora pe dispozitive mobile iOS.

Interfața dealer-ului conține mai multe secțiuni statice la fel ca și în cazul interfeței detaliilor unui automobil. Astfel interfața detaliilor unui dealer este împărțită în următoarele secțiuni:

detaliile dealer-ului ce conține un UIImage cu logo-ul companiei, într-o formă circulară și sub aceasta denumirea companiei și orele de lucru;

3 butoane rotunde cu imagini specifice pentru apelare, trimitere e-mail și trimitere sms;

secțiune destinată pentru notele companiei, unde este inclusă un View pentru afișarea stelelor, care sunt prelucrate de către framework-ul Cosmos, un TextView ce afișează cel mai recent review lăsat de clienți;

un text care afișează adresa companiei;

un buton ce permite afișarea tuturor automobilelor propuse de către dealer;

un View ce la fel conține o hartă unde este plasată locația dealer-ului, iar harta este prelucrată de către framework-ul Google Maps.

În bara de navigare a controllerului de navigare pot fi plasate anumite elemente, precum ar fi butoane care să îndeplinească anumite acțiuni. Pe pagina principală persistă 2 butoane care sunt pentru a deschide pagina de căutare și celălalt pentru sortarea automobilelor, care deschide un dropdown cu posibiltățile de sortare disponibile(cele mai recente automobile, sortate după preț crescător, sortate după preț descrescător), iar la pagina cu detalii despre automobil se afișează un buton pentru închirierea acestuia și butonul de întoarcere la pagina precedentă care este automat plasat în partea stângă a barei de navigare de către controller. Aceste butoane sunt afișate în figura 3.5.

Pentru elaborarea aplicației mobile pe platforma Android sunt utilizate Layout-urile, care reprezintă o structură pentru interfața vizuală, la fel ca o activitate. Layout-urie sunt niște fișiere XML elaborate special pentru vocabularul Android, în care cu ușurință se pot plasa elementele necesare la fel ca și crearea unor pagini HTML. Pe lângă fișierele scrise în XML, este posibilitatea de a adăuga și aranja elementele pe pagină utilizând editorul vizulal. În figura 3.6 este prezentat editorul vizual și pagina de detalii a dealer-ului. Astel se poate observa că se folosește un LinearLayout pentru a putea afișa elementele paginii într-o singură pagină și ca aceasta să devina derulabilă. Fiecare secțiune a paginii are elementele sale, astel în prima secțiune sunt plasate un CircleImageView, și două TextView-uri, în care sunt afișate imaginea dealer-ului, denumirea și orele de lucru al acestuia. Imaginea dealerului este afișată într-un CircleImageView, acesta fiind un framework specializat în rotungirea imaginilor. În secțiunea următoare sunt trei butoane cu funcțiile de apelare, trimitere a unui email sau a unui mesaj sms. În secțiunea următoare este afișată partea cu review-uri a dealer-ului, unde este afișat ultimul review și o bară cu stele ce indică ratinguul total, care la apăsarea pe această secțiune duce la pagina cu review-urile utilizatorilor și posibilitatea de a adăuga un review nou. Iar această secțiune este urmată de secțiunea în care este afișată adresa dealer-ului introdusă într-un TextView. Aceasta fiind urmată de o secțiune care la apăsare pe aceasta va deschide o activitate nouă ce va conține toate mașinile disponibile de la dealer-ul curent. În ultima sectiune se află un MapView care afișează poziția pe hartă a automobilului utilizând Google Maps care are încorporat toate cele necesare pentru o utilizare cât mai simplă a aceseia. Astfel pentru aranjarea în pagină a elementelor din layout se utilizează constrângerile(ConstraintLayout) ca sa fie proporționale dimensiunile pe orice dispozitiv ce rulează aplicația, indiferent de dimensiunile ecranului deoarece dispozitivele android au o mulțime de dimensiuni.

Pentru implementarea paginii principale a aplicației se utilizează RecyclerView, ce reprezintă o versiune îmbunătățită a ListView-ului, cu o performanță sporită și alte beneficii. Astfel în acest RecyclerView este afișată lista automobilelor disponibile.

<android.support.v4.widget.SwipeRefreshLayout android:id="@+id/swifeRefresh" android:layout_width="match_parent" android:layout_height="match_parent">

<android.support.v7.widget.RecyclerView

android:id="@+id/car_list" android:layout_width="match_parent" android:layout_height="match_parent" />

</android.support.v4.widget.SwipeRefreshLayout>

<ProgressBar

android:id="@+id/main_progress" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" />

În această secțiune de cod se poate observa RecyclerView-ul cu automobile, acesta fiind intergrat într-un SwipeRefreshLayout care permite reîncărcarea paginii printr-o simplă glisare în jos, astfel permite reânnoirea listei de automobile și afișarea automobilelor recent apărute. Iar pentru o estetică mai clară pentru utilizator se afișează un ProgressBar în timp ce se reâncarcă datele, asta în caz că conexiunea la internet este slabă sau lipsește, astfel utilizatorul înțelege că datele încă nu au fost descărcate și descărcarea acestora durează ceva timp.

Un plus pentru utilizarea MVC este că codul poate fi refolosit, ca și în cazul dat, pentru interfețele activity_main, activity_car_dealer_cars se utilizează interfața item_car, care reprezintă o celulă din lista implimentată în aceste interfețe. Astfel nu este necesar de implimentat acelașii tip de celulă cu acelașii design pentru 2 pagini diferite, economisind timp și îmbunătățind performanța. Modelul celulei poate fi observat în figura 3.7, unde sunt afișate 2 TextView-uri în care sunt plasate numele și prețul automobilului dar și imaginea

Cât și iOS dar și Android au posibilitatea de a adăuga dependențe adăugătoare, care sunt create de comunitate pentru a adăuga funcționalități noi aplicației sau pentru a optimiza codul și munca dezvoltatorilor. Pentru adăugarea dependențelor pe platforma iOS se utilizează CocoaPods, care este un manager de dependențe scris in Ruby și conține peste 44 de mii de librării disponibile. Iar pentru adăugarea dependențelor se folosește terminalulde sistem(figura 3.8), astfel integrarea este simplă și fără prea mult efort.

Figura 3.8 – Instalarea dependențelor CocoaPods utilizînd terminalul

Pentru adăugarea dependențelor pe platforma Android se folosește Gradle, ceea ce simplifică adăugarea dependențelor într-o apicație. Dependențele pot fi localizate fie pe caclulatorul personal, fie pe un repozitoriu distant, ceea ce oferă o diversitate în adăugarea acestora.

dependencies {

compile fileTree(dir: 'libs', include: ['*.jar'])

androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { exclude group: 'com.android.support', module: 'support-annotations'

})

compile 'com.android.support:appcompat-v7:26.+'

compile 'com.android.support.constraint:constraint-layout:1.0.2' compile 'com.android.support:recyclerview-v7:26.+' compile 'com.android.support:cardview-v7:26.+' testCompile 'junit:junit:4.12'

compile 'com.google.android.gms:play-services-maps:11.0.4' compile 'de.hdodenhof:circleimageview:2.1.0' compile 'com.android.volley:volley:1.0.0'

compile 'com.github.JakeWharton:ViewPagerIndicator:2.4.1' }

Din câte se poate observa în codul de mai sus, dependențele sunt plasate pe repozitorii distante, iar inițializarea acestora se face automat la salvarea fișierului Gradle, astfel atunci are loc descărcarea și adăugarea acestor dependențe în proiect. La finalizarea descărcării apare un mesaj de success în caz că dependențele au fost descărcate cu success, sau un mesaj de eroare și numele dependenței unde a apărut eroarea. În așa caz dezvoltatorul poate observa cu ușurință care dependențe dau eroare și care este cauza erorii.

class CarCard {

private var carID : String private var carName : String private var carPrice : String private var carImage : URL … }

class ReviewCard {

private var reviewName : String private var reviewDescription : String private var reviewStars : Int

}

Pentru încărcarea datelor în tabele se creează modelele speciale precum CarCard, ReviewCard, pentru a salva datele necesare și a dirija cu acestea mult mai simplu în cadrul tabelelor. Astfel aceste clase se folosesc pentru a încărca datele în celulele tabelelor, fiind transmis celulei un obiect de acest tip, iar celula îl prelucrează încărcând datele necesare în câmpurile necesare(url-ul la imagine la imagine, numele la textul destinat numelui, iar prețul la textul destinat prețului), astfel în codul următor se poate observa cum celula primește un obiect de tip CarCard, și încarcă datele acestuia în cîmpurile necesare. Pentru încărcarea imaginilor se folosește pod-ul AlamofireImage, pentru a descărca imaginile asincron și a exclude erorile în timpul descărcării acestora.

func prepare(data: CarCard) {

carName.text = data.getCarName() carPrice.text = data.getCarPrice()

carImage.af_setImage(withURL: data.getCarImage()) }

Pentru platforma Android la fel am creat aceleași modele ca si pe platforma iOS, deoarece aplicațiile sunt asemenea și datele se prelucrează la fel. Doar că pentru încărcarea datelor în RecylerView se inițiază Adapterul necesar pentru îcărcarea datelor în celule, adăugarea acestora și inițierea Listenerilor, care ascultă acțiunile utilizatorului, și astfel la apăsarea unei celule din RecyclerView să se redirecționeze spre pagina de detalii a automobilului.

public class CarCard { private String carID; private String carName; private String carPrice; private String carImage; … }

public class ReviewCard { private String reviewName; private String reviewDescription; private Integer reviewRating;

}

Deoarece iOS nu dispune de meniu derulant, care este necesar pentru selectarea tipului de sortare al automobilelor disponibile, atunci se adaugă un pod ajutător, care creează acest meniu asemănător celui de la Android. Pod-ul TBDropdownMenu permite o configurare mult mai detaliată, începând cu culori și terminând cu afișarea opțiunilor disponibile. Acest meniu derulant este afișat la apăsarea butonului de filtrare care este fixat pe bara de navigare în partea dreaptă.

let item1 = DropdownItem(title: "Recent")

let item2 = DropdownItem(title: "Price: lowest first") let item3 = DropdownItem(title: "Price: highest first")

let items = [item1, item2, item3]

let menuView = DropdownMenu(navigationController: navigationController!, items: items, selectedRow: selectedFilter)

menuView.textColor = AppColors.carTitle

menuView.tableViewBackgroundColor = AppColors.background menuView.cellBackgroundColor = AppColors.background menuView.highlightColor = AppColors.carTitle menuView.delegate = self menuView.showMenu()

Din codul scris mai sus se poate observa că meniul cuprinde 3 câmpuri, care la apăsarea acestora sortează automobilele dupa preț crescător, descrescător sau cele mai recente automobile apărute. Cum a fost spus, acest pod permite customizarea meniului după preferințe, astfel se stabilește o culoare asemănătoare cu fundalul, ca să fie în acelașă ton de culori, se dezactivează culoarea celulei selectate, și se afișează o bifă în drept cu filtrul selectat(figura 3.9).

Figura 3.9 – Meniul derulant pentru filtrarea automobilelor pe iOS

Pentru sistemul Android, adăugarea meniului pentru filtrare este mult mai simplă, el având deja opțiunile necesare deja disponibile, iar pentru crearea meniului derulant este necesar de creat doar un simplu fișier XML special pentru meniu ce conține aceste opțiuni de sortare disponibile.

<group

android:id="@+id/filter_menu" android:checkableBehavior="all">

<item

android:id="@+id/one" android:title="Recent" />

<item

android:id="@+id/two"

android:title="Price: lowest first" />

<item

android:id="@+id/three"

android:title="Price: highest first" /> </group>

Astfel când a fost creat fișierul ce conține acest meniu, el trebuie doar adăugat în paginile unde este necesar acest tip de meniu prin inițierea acestuia în timpul inițierii activității. Iar pentru afișarea tipului de sortare utilizat la fel ca și la iOS este poziționată o bifă în drept cu meniul(Figura 3.10).

Figura 3.10 – Meniul derulant pentru filtrarea automobilelor pe Android

Atât la iOS cât și la Android, pentru salvarea opțiunii selectate pentru filtrare, la inițierea activității se inițiază o variabilă cu 0, acesta fiind id-ul pentru sortarea automobilelor cele mai recente, iar pentru sortarea după preț în ordine crescătoare sau descrescătoare sunt utilizate valorile 1 sau 2. Deci în dependență de aceste valori se afișează bifa în drept cu fiecare poziție a meniului derulant dar și se ordonează și afișează lista de automobile în această ordine.

Meniurile derulante sunt folositoare în aceste cazuri, ele oferind posibilitatea de alege dintre diferite opțiuni, el fiind compact și simplu de utilizat pe înțelesul oricărui utilizator fără prea mult efort, astfel este cel mai des întâlnit în cazul când este necesar de adăugat un submeniu rapid pentru sortare sau a unui meniu simplu cu diferite opțiuni ce pot fi accesate. În acest caz Android are un mic avantaj din cauză că el are aceste opțiuni deja integrate în sistem, dar nici iOS nu este departe de așa opțiuni, el avînd stilul său dar și o mulțime de utilitîi adîugîtoare pentru a integra un meniu asemănător ca și cel de la Android pentru a crea aplicații asemănătoare pe ambele platforme.

Pentru a adăuga un stil aplicației, imaginea dealer-ului a fost retușată la formă circulară(figura 3.11), pentru a intra în concordanță cu butoanele rotunde de pe pagină, dar și pentru că imaginile circulare se încadrează mult mai ușor în ambianța aplicației dar și sunt des întâlnite în asa gen de aplicații. Iar în caz contrar că dealer-ul nu dispune de o imagine, atunci se afișează o imagine standartă.

Figura 3.11 – Imaginea dealer-ului

Pentru platforma iOS este simplu de a crea o imagine circulară, aceasta fiind posibil doar prin adăugarea rotungirii colțurilor și anume rotungirea acestora până la punctul ca imaginea să preia o formă circulară. Pentru asta se ia rotungirea aceasta de dimensiunea unei raze, sau mai bine zis – jumătate din înățimea imaginii. Iar pentru adăugarea unei borduri la fel se definește culoarea acesteia și dimensiunea statică, în cazul nostru o dimensiune de 3 pixeli și o bordură albă.

dealerLogo.layer.backgroundColor = UIColor.white.cgColor dealerLogo.layer.borderWidth = 3

dealerLogo.layer.borderColor = AppColors.carTitle.cgColor dealerLogo.layer.cornerRadius = dealerLogo.frame.height/2

Pentru platforma Android adăugarea unei imagini circulare nu este așa simplă, doar prin retușarea colțurilor imaginii, deoarece Android nu dispune de așa funcționalitate în cadrul dezvoltării aplicațiilor, iar pentru aceasta se utilizează o dependență ajutătoare, care transforma imaginile simple direct în imagini circulare. Dependența CircleImage înlocuiește unde este necesar ImageView-urile cu View-uri speciale care sunt asemănătoare, doar că deja ele prelucraeză imaginea și o afișează sub formă circulară, independent de imagine și dimensiunea acesteia.

<de.hdodenhof.circleimageview.CircleImageView xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/carDealerImage" android:layout_width="150dp" android:layout_height="150dp" android:layout_gravity="center_vertical" android:layout_marginTop="10dp" app:civ_border_color="#ffffff" app:civ_border_width="2dp" app:civ_fill_color="#ffffff"

app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" />

Din câte se poate vedea în codul de mai sus este afișat codul XML al imaginii circulare, care la fel are o dimensiune fixă și la fel cuprinde o bordură de culoare albă de dimensiunea de 2 pixeli pentru a oferi o estetică imaginii afișate.

Pentru aplicațiile date este implementată funcționalitatea de a verifica conexiunea la internet. Astfel la lansarea aplicației se verifică conexiunea prin Wifi sau rețeaua celulară, iar în cazul că aceasta lipsește se afișează un mesaj de eroare(figura 3.12) ce permite utilizatorului să deschidă setările și să activeze conexiunea la internet. Odată cu lansarea aplicației se pornesc funcții speciale care ascultă această funcționalitate și în caz că în timpul utilizării aplicației se oprește conexiunea la internet se afișează mesajul de eroare, iar odată cu pornirea conexiunii se reîncarcă datele în aplicație și se afișează la ecran.

Figura 3.12 – Mesajul de eroare a conexiunii la internet

Pentru aceasta este utilizat pod-ul Reachability ce creează aceste funcții ce ascultă și urmăresc conexiunea la internet. Odată cu lansarea aplicației se pornesc funcțiile de urmărire, ce reacționează la fiecare schimbare a statutului rețelei, fie oprirea conexiunii, fie pornirea acesteia, fie schimbarea conexiunii de pe wifi pe rețeaua celulara sau invers, ceea ce este foarte folositor în diferite situații când conexiunea celulară nu este binevenită în descărcarea datelor de dimensiuni mari.

Fiecare automobil poate avea una sau mai multe imagini, care sunt afișate utilizatorului. De aceea pentru a le afișa pe toate într-un mod mai simplu, se folosește un slideshow, care afișează imaginile într-o anumită ordine și le schimbă între ele automat sau la interacțiunea acestuia.

Pentru platforma iOS se folosește pod-ul ImageSlideshow, astfel în partea de sus a paginii de detalii se introduce un View, care implementeaza acest pod și preia funcționalitatea acestuia. La accesarea paginii de detalii a automobilului, se trimit către View o listă de adrese URL, deoarece ImageSlideshow lucreaza cu AlamofireImage care descarcă imaginile asincron de pe internet și le trimite în slideshow automat fără prea mult efort din partea dezvoltatorului.

self.imageSlideshow.backgroundColor = AppColors.background self.imageSlideshow.slideshowInterval = 5.0

self.imageSlideshow.pageControlPosition = PageControlPosition.insideScrollView self.imageSlideshow.pageControl.currentPageIndicatorTintColor = AppColors.navigationBar self.imageSlideshow.pageControl.pageIndicatorTintColor = UIColor.white self.imageSlideshow.contentScaleMode = UIViewContentMode.scaleAspectFill …

self.imageSlideshow.setImageInputs(imageImputs)

Din codul reprezentat mai sus, se poate vedea că view-ul ce deține acest slideshow va avea culoarea fundalului în timp ce se descarcă imaginile, iar fiecare dintre imagini se va schimba la fiecare 5 secunde. În partea de jos a slideshow-ului sunt prezentate câteva puncte/indicatoare care arată numărul total al imaginilor li imaginea curentă care este afișată. Iar în partea dreaptă a acestul view, deassupra a fost plasat prețul automobilului. Rezultatul final poate fi văzut în figura 3.13.

Figura 3.13 – ImageSlideshow-ul cu pe iOS

Pe Android pentru implementarea acestui slideshow se creează un adapter special ce extinde un PagerAdapter, care este asemănător cu slideshow-ul necesar. La instanțierea acestui adapter se trimit adresele URL a imaginilor, iar cu ajutorul NetworkImageView se descarcă și se adaugă aceste imagini în adapter una după alta. Iar pentru schimbarea automată a imaginilor se instanțiază și un timer care la fiecare 4 secunde schimbă imaginile.

NetworkImageView networkImageView = (NetworkImageView) imageLayout.findViewById(R.id.slideImage );

ImageLoader imageLoader = VolleySingleton.getInstance().getImageLoader(); networkImageView.setImageUrl(mImageUrls.get(position), imageLoader); container.addView(imageLayout, 0);

Fiindcă imaginile se folosesc de PagerAdapter, iar acesta nu permite afișarea unor indicatoare care să afișeze numărul total de imagini și imaginea ce este afișată se utilizează o librărie – CirclePageIndicator, care se leagă de PagerAdapter și preia datele de acolo precum ar fi numărul de imagini și imaginea curentă care este afișată, astfel el prelucrează datele și creează un indicator asemănător celui de la iOS. Rezultatul final poate fi observat în figura 3.14.

Figura 3.14 – Slideshow-ul pe Android

În cadrul aplicației se utilizează hărțile Google, care sunt utilizate pentru afișarea locației automobilului pe hartă, astfel utilizatorul poate cu ușurință găsi poziția acestuia sau să vadă poziția dealer-ului. Se utilizează hărțile Google deoarece ele sunt cele mai răspîndite și oferă detalizare maximă pentru găsirea unei locații.

Platforma iOS nu dispune de acces direct la hărțile Google, accesul fiind oferit doar prin adăugarea pod-ului GoogleMaps care este dezvoltat de către Google și cu ajutorul căruia dezvoltatorul poate cu ușurință integra harta în aplicație. Pentru integrarea hărților este necesară o cheie de accesare a api-ului oferit de către google, iar această cheie poate fi cu ușurință creată în consola Google, care oferă acces la toate serviciile oferite de Google. Iar după crearea cheii de access, aceasta se introduce în aplicație și se inițializează pod-ul odată cu pornirea aplicației în AppDelegate.

GMSServices.provideAPIKey(Constants.googleKey) …

În codul afișat mai sus, se poate observa cum la pornirea aplicației se inițializează pod-ul GoogleMaps și îi este oferită cheia de access la API. În paginile de detalii a automobilului și a dealer-ului se adaugă un View care implimentează GoogleMaps, astfel toate funcționalitățile disponibile precum ar fi navigarea pe hartă, mărirea sau micșorarea, adăugarea punctelor de referință și multe alte posibilități sunt inițializate și ele în acest View.

DispatchQueue.main.async(execute: { () -> Void in

let camera: GMSCameraPosition = GMSCameraPosition.camera(withLatitude: lat, longitude: long, zoom: 17.0) self.carMapView.camera = camera

let marker = GMSMarker()

marker.position = CLLocationCoordinate2D(latitude: lat, longitude: long)

marker.map = self.carMapView

})

În codul afișat mai sus se poate observa cum asincron se inițializează harta pe pagina de detalii a automobilului, unde se plasează un punct anumit, care reprezintă locația curentă a automobilului, acest punct fiind plasat la o anumită latitudine și longitudine, iar camera este direcționată spre acest punct ca să nu apară punctul într-o regiune iar utilizatorul să nu știe despre acesta și camera să fie la poziția inițială. Astfel camera este la fel poziționată în punctul unde poziționat și marker-ul pentru ca utilizatorul să vadă deodată locația automobilului.

Platforma Android, fiind dezvoltată de către Google are deja implementată hărțile Google în sistem și nu necesită dependențe adăugătoare pentru utilizarea acestora. Însă pentru utilizarea acestora la fel ca și la iOS este necesară cheia de acces la API.

mapView.getMapAsync(new OnMapReadyCallback() {

@Override

public void onMapReady(GoogleMap googleMap) { gMap = googleMap;

Marker marker = gMap.addMarker(new

MarkerOptions().position(position).title(markerText));

CameraUpdate cameraUpdate =

CameraUpdateFactory.newLatLngZoom(position, 16);

gMap.animateCamera(cameraUpdate);

}

});

În codul de mai sus este arătat cum asincron se inițializează harta, și la fel ca la iOS se setează un marker cu latitudinea și longitudinea oferită și se adaugă un text ajutător ce reprezintă denumirea companiei ce oferă acest automobil în chirie. Pentru afișarea markerului în centrul hărții, la fel se repoziționează camera și se centrează asupra markerului. Un exemplu detaliat se poate observa în figura 3.15.

Figura 3.15 – Localizarea pe harta Google a automobilului

Pentru a vedea care sunt părerile utilizatorilor despre o anumită companie de chirie a automobilelor se folosește un sitem de plasare a părerilor pentru o anumită companie, astfel utilizatorii pot vedea o notă medie care se calculează din notele tuturor utilizatorilor dar și părerile acestora într-o listă. Astfel pe platforma iOS se utilizează un pod adăugător ce creează o bară cu stele, în care poate fi afișată nota utilizatorului pentru serviciul oferit de această companie. Pod-ul Cosmos presupune un simplu View, care implimentează această clasă Cosmos pentru prealuarea funcționalului acesteia, precum numărul stelelor, valoarea acestora și culoarea acestora. În Android nu este necesar nici un fel de dependență adăugătoare, deoarece acesta conține RatingBar care este asemănător cu cel de la iOS, și are același funcțional. Dezvoltatorul având posibilitatea de a configura numărul de stele dar și nota medie afișată. În cazul când nota și comentariile utilizatorilor lipsesc, această categorie este complet ascunsă pentru că nu sunt disponibile date despre note și comentarii, iar prezența ei este inutilă în acest caz.

În cadrul aplicației pot interveni diferite încetiniri în descărcarea datelor de pe server, astfel pentru a nu duce utilizatorul în confuzie se utilizează diferite animații de așteptare în timp ce se încarcă datele de pe server. Pe platforma iOS se utilizează pod-ul PKHUD care blochează acțiunea utilizatorului pe întreaga durată de încărcare și afișează în centrul ecranului o animație de încărcare ce se pornește odată cu inițializarea controllerului și se termină fie cu succes în cazul că datele au fost descărcate cu succes, sau cu eroare în caz că sa pierdut conexiunea la internet sau automobilul nu a fost găsit sau altă eroare, după care se întoarce la controllerul precedent, ceea ce se poate observa în următoarea secvență de cod.

override func viewDidLoad() {

HUD.show(.progress)

getData(success: { (data) in

HUD.hide()

}, failure: { (data) in

HUD.flash(.labeledError(title: "", subtitle: data), delay: 2.0) { _ in self.navigationController?.popViewController(animated: true)

}

}) }

Pe platforma Android se creează un fișiser XML aparte, unde este poziționat la centru un ProgressBar care este poziționat la centru, acesta învârtindu-se la infinit. În timpul inițierii controllerului, se afișează acest ProgressBar până se descarcă datele apoi se ascunde acest progressBar la încărcarea datelor în controller. Astfel în figura 3.16 sunt prezentate aceste animații de încărcare.

Figura 3.16 – Animația de încărcare

În cadrul aplicației sunt necesare funcționalitățile de apelare, trimitere a unui mesaj sau a unui email. Fiecare sistem de operare prelucrează aceste date în felul său, astfel încât sistemul iOS fiind un sistem închis, și neavând posibilitatea de a efectua aceste funcții direct, dar doar prin interacțiunea și aprobarea utilizatorului sporește nivelul de securitate în cazul scurgerii de informații sau a apelării neintenționate a diferitor numere de telefon în scopuri frauduloase. La fel si Android dispune de așa funcționalități de interacțiune cu utilizatorul pentru a efectua așa tip de acțiuni.

În cadrul sistemului iOS pentru apelarea unui număr de telefon se pune extensia tel:// în fața numărului de telefon și este accesat ca o adresă url, astfel sistemul vede că aceasta este o comandă de apelare a unui număr de telefon și avertizează utilizatorul că acesta va efectua un apel telefonic, care după confirmarea acestuia efectuează apelul. În cadrul mesajelor și a email-ului se utilizează aplicația de mesagerie și email a sistemului, pentru a trimite un mesaj sau email.

if(MFMessageComposeViewController.canSendText()) { let controller = MFMessageComposeViewController()

controller.body = "Hi! I'm interested in you car deals, can you give me more information about your cars ?"

controller.recipients = [(dealerDetails?.messageNumber)!] controller.messageComposeDelegate = self

self.present(controller, animated: true, completion: nil)

}

În codul de mai sus se poate observa că la apăsarea comenzii de tirmitere a unui mesaj, se verifică dacă este prezentă mesageria, asta în caz că aplicația rulează pe un iPod în care nu este prezentă și aplicația va cădea. În caz că mesageria este prezentă, se completează forma de mesaj cu textul mesajului și destinatarul, în cazul dat el fiind compania de chirie a automobilelor. La completarea acestor câmpuri se deschide fereastra de mesagerie cu aceste câmpuri deja completate și se cere deja acțiunea utilizatorului pentru a tirmite mesajul sau a anula trimiterea acestuia.

Pentru trimiterea unui email la fel se verifică prezența aplicației de trimitere a unui email, în caz că aplicația este prezentă, se completează la fel câmpurile cu destinatar, subiect și textul mesajului, după care se deschide fereastra de email care așteaptă la fel aprobarea utilizatorului pentru trimiterea email-ului sau nu. Fereastra de aprobare este afișată în figura 3.17, unde se poate vedea deschisă mesageria implicită și așteaptă aprobarea utilizatorului pentru a trimite mesajul.

Figura 3.17 – Fereastra de aprobare pentru trimiterea unui email

Sistemul Android dispune la fel de opțiunile de a apela, a trimite un mesaj sau a unui email. Pentru apelarea unui număr de telefon în fața acestuia se pune tel: și se apelează Intent-ul de deschidere a telefonului pentru a apela un număr de telefon, iar acest număr este trimis deodată cu apelare Intent-ului. Când se pornește activitatea telefonului, automat se introduce numărul de telefon în cadranul de introducere a numărului de telefon și la fel ca la iOS se așteaptă interacțiunea utilizatorului pentru a apela numărul de telefon sau nu. În caz că nu se poate efectua apelul sua nu a fost găsită aplicația de apelare telefonică se afișează un mesaj de eroare.

Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("sms:" + car.messageNumber)); intent.putExtra("sms_body", "Hi! I'm interested in your " + car.carName + " car, can I get more details about this car?"); try {

startActivity(intent);

} catch (android.content.ActivityNotFoundException ex) {

Utility.showToast("Could not send the SMS.");

}

În codul de mai sus se poate observa cum este creat intent-ul pentru trimiterea unui mesaj sms. Astfel se inițiază un nou intent care are ca scop deschiderea mesageriei, în caz contrar se afișează un mesaj de eroare. La deschiderea acesteia se trimit datele de completare a mesajului, precum ar fi numărul de telefon și textul mesajului. Pentru trimiterea unu email la fel se creează un intent asemănător care deschide aplicația de email implicită și completează câmpurile cu datele necesare și la fel ca la mesagerie se așteaptă interacțiunea utilizatorului pentru a trimite mesajul sau pentru a anula trimiterea acestuia.

Odată cu deschiderea aplicațiilor de mesagerie sau email, utilizatorul poate vedea ce mesaj se trimite, plus poate edita mesajul după placul său pentru a putea cere mai multe detalii de la companie. Astfel este securizată trimiterea mesajelor sau apelurilor și compania nu poate primi detalii private despre utilizator fără voia acestuia, protejând niveul de securitate a datelor cu caracter personal.

Deoarece aplicația este cu caracter economic și oferă clienților anumite produse, în cazul dat automobile, atunci în aplicație este necesar să persiste și modulul de căutare a automobilelor dorite. Cât și Android dar și iOS dispun de aceste opțiuni, fiecare în modul său implementat. Pentru aplicația Android se utilizează SearchManager, care creează un buton de căutare în partea dreaptă a barei de navigare. La apăsarea acestui buton se deschide un câmp de căutare, care este afișat în figura 3.18, unde pot fi introduse cuvinte cheie pentru căutarea unui automobil.

Figura 3.18 – Bara de căutare în sistemul Android

La căutarea unui anumit model de automobile se face o cerere la server, care returnează o listă de automobile după specificațiile căutate. În caz că lista este goală se afișează că nu a fost găsit nici un automobil, în caz contrar se afișează numărul de automobile găsite și lista de automobile. Astfel utilizatorul are o alegere și poate selecta automobilul care îl consideră cel mai optimal.

În cadrul sistemului iOS s-a creat o interfață aparte pentru căutarea automobilelor, unde în partea de sus a paginii este afișată o bară de căutare, iar sub aceasta este afișată o listă de automobile găsite în urma căutării după anumite cuvinte cheie și numărul de automobile găsite. Iar în bara de navigare este prezent butonul de sortare a automobilelor după criteriile stabilite. Pagina dată este afișată în figura 3.19.

Figura 3.19 – Rezultatele căutării unui model de automobile

Ca orice aplicație care este legată de un server, este necesară conexiunea la internet și comunicarea cu acesta. În cazul dat aplicația comunică cu serverul și primește răspuns sub formă de date JSON. Aceste date JSON sunt scrise ca perechi de nume și valoare, astfel numele reprezintă numele valorii primite și acesta se notează între gilimele, iar în a doua coloană este valoarea care este primită.

Sistemul iOS dispune de posibilitatea de a crea cereri HTTP, dar este mult prea complexă, de aceea sunt librării alternative care efectuează aceste operațiuni mult mai simplu și mai eficient. Pod-ul Alamofire oferă o interfață elegantă și simplificată în domeniul cererilor HTTP.

Alamofire.request(url).responseJSON { (response) in if(response.result.isSuccess) {

if((response.response?.statusCode)! == 200) {

success(cars)

} else {

failure("Data not found!")

} } else {

failure("Connection error!")

}

}

În codul de mai sus se poate vedea cum se face o cerere la server cu ajutorul lui Alamofire, care primește răspuns în formă de JSON. Astfel el face o cerere la server și primește date înapoi. La primirea datelor se verifică dacă sa efectuat cu success cererea, în caz contrar se afișează un mesaj de eroare precum că este o problemă cu conexiunea. Dacă cererea a fost efectuată cu success, se verifcă codul de răspuns de la server, în caz că acesta diferă de codul 200, atunci sunt careva probleme la server și nu au fost găsite datele, astfel la fel se afișează un mesaj de eroare precum că datele nu au fost găsite. Dacă și codul de răspuns este cu success atunci se prelucrează datele primite înapoi.

Cererile spre server au aceeași sintaxă ca și în codul precedent, unica ce diferă sunt adresele url care sunt accesate în care sunt indicate datele necesare precum ar fi cuvintele cheie căutate, id-ul automobilului sau a companiei ce oferă servicii de chirie. Astfel în dependență de link-ul accesat și datele JSON primite diferă.

Cererile spre server se execută asincron, și pentru a evita încetinirile sau oprirea aplicației în cazul unor date enorme sau a unei conexiuni lente se utilizează Closures. Closures sunt niște blocuri funcționale care sunt transmise și folosite în cod. Closures din limbajul Swift sunt asemănătoare cu expresiile lambda în alte limbaje. Closures în Swift au un stil curat și clar, cu optimizări care încurajează o sintaxă scurtă și curată în scenariile comune[12].

private static func getCarList(url: String, page : Int,

success: @escaping (_ data: [CarCard]) -> Void, failure: @escaping (_ error: String) -> Void) { ………

}

În codul de mai sus se poate observa aceste closures care sunt implimentate în cadrul metodei de preluarea a listei de automobile. Astfel sunt transmiși către metodă adresa de unde sunt descărcate automobilele, și pagina care este afișată, după care sunt implementate două expresii de tip closure, care sunt apelate în caz de success sau de eroare. Astfel în caz de eroare ca rezultat se întoarce către cod un string cu tipul erorii care va fi afișată la ecran, iar în caz de success se returnează o listă de date despre automobil, aceasta fiind un model creat pentru păstrarea datelor într-o formă mai compactă și ușor de utilizat și prelucrat.

APIClient.getRecentCarList(page: currentPage, success: { (data) in self.cars = data

self.maxCarsShowed = data.count self.tableView.reloadData()

HUD.hide()

}, failure: { _ in

HUD.flash(.labeledError(title: "", subtitle: "Error!"), delay: 2.0)

})

În codul de mai sus este apelată metoda de descărcare a automobilelor recent apărute, care este utilizată în MainViewController. Aici se poate observa că se apelează clasa APIClient, și metoda getRecentCarList care este o metodă statică și nu necesită inițializarea unei variabile de acest tip. Metoda dată are hardcodat în interiorul acesteia link-ul necesar pentru accesarea și descărcarea datelor necesare pentru pagina principală și anume automobilele recent apărute. Unica valoare ce este trimisă către metodă este pagina accesată. Deoarece metoda conține două closures, se definesc părțile de cod ce vor fi executate la apelarea acestora, astfel este closure success care este apelat când datele au fost descărcate și prelucrate cu success iar ca răspuns primește o listă de obiecte CarCard, aceste obiecte fiind introduse în lista controllerului și se reâncarcă pagina controllerului pentru a afișa lista de automobile. În cazul că este apelat closure failure atunci a apărut o eroare în timpul descărcării datelor sau a conexiunii cu serverul, și astfel se afișează un mesaj de eroare primit înapoi de closure.

Pentru prelucrarea datelor JSON în Swift se utilizează librăria SwiftyJSON, care permite prelucrarea cu ușurință a datelor de tip JSON primite de la server. Această librărie cu ușurință poate fi integrată cu Alamofire pentru a prelua și prelucra datele.

let data = JSON(data: response.data!) var cars = [CarCard]() if data.count != 0 { for i in 0…data.count-1 {

let car = CarCard(ID: data[i]["slug"].stringValue, name: data[i]["offer"].stringValue, price: data[i]["price"].stringValue,

image: URLAdress.getImageURL(image: data[i]["carImages"][0]["name"].stringValue)) cars.append(car)

}

}

În codul de mai sus se poate observa cum se preia datele primite ca răspuns de la cererea efectuată către server în variabila response. Astfel aceste date se transformă în format JSON și se păstrază în variabila data, după care se creează o listă de elemente CarCard care este vidă pentru a putea fi adăugate datele ulterior. Datele primite în data sunt sub formă de listă salvate, astfel se preia fiecare element al acestei liste și se extrag datele necesare. SwiftyJSON permite preluarea datelor într-o valoare necesară, în cazul dat se preia id-ul, numele, prețul și adresa imaginii în format string, dar în cazul imaginii acesta recepționează doar denumirea imaginii și este necesar ca aceasta să fie prelucrată în adresă specială pentru a putea vizualiza imaginea. După preluarea acestor date, acestea sunt deodată salvate într-o variabilă de model CarCard, care apoi este adăugată în lista de elemente. La final această listă deja având careva elemente este trimisă mai departe spre controller care încarcă aceste modele în celulele tabelelor.

În cadrul prelucrării datelor primite despre detaliile unui automobil la fel se primește un JSON, dar care este un simplu obiect ce conține mai multe detalii și o listă de de imagini despre automobil, acestea fiind o listă de elemente string. Pentru aceasta se prelucrează întâi lista de imagini pentru a putea fi adăugată în modelul CarDetails la inițializarea acestuia, ceea ce se poate observa în secvența de cod de mai jos.

var carImages = [String]()

let jsonArr = data["carImages"].arrayValue for image in jsonArr {

carImages.append(URLAdress.getImageURL(image: image["name"].stringValue)) }

Din secvența de cod de mai sus se poate observa cum se preia o porțiune din tot JSONul primit și anume lista de imagini, aceasta oferind doar denumirile imaginilor, după care sunt prelucrate și transformate în adrese url pentru o operare mult mai simplă în cadrul controllerului.

În cadrul aplicației a fost definită o clasa APIClient care se ocupă cu prelucrarea și descărcarea datelor de pe server, în aceasta este o metodă generală privată care preia datele de pe net dar conține mai multe atribute care sunt setate în dependență de necesitate. Iar în această clasă sunt prezente și metodele publice specifice pentru fiecare necesitate precum preluarea automobilelor în ordinea creșterii prețului, sau precum ar fi lista de automobile a unei companii, toate apelând aceeași metodă privată dar se trimite adresa url din care să fie preluate datele. Tot aceeași implementare este și în cadrul aplicației pentru Android. Aplicația Android la fel dispune de o librările specializată în cadrul prelucrării cererilor din rețea – Volley. Aceasta fiind o librărie care ușurează implementarea cererilor în rețea, făcând mai ușoară și mai plăcută, dar în general oferind o performață sporită. Această librărie mai include în sine și parsarea datelor JSON, ceea ce exclude folosirea unor librării adiționale pentru parsarea acestuia.

JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(Request.Method.GET, url, null, new Response.Listener<JSONArray>() {

@Override

public void onResponse(JSONArray response) {

}

}, new Response.ErrorListener() {

@Override

public void onErrorResponse(VolleyError error) {

}

});

requestQueue.add(jsonArrayRequest);

În codul de mai sus se poate observa cum pentru efectuarea unei cereri către server se inițiază un nou JsonArrayRequest care utilizează metoda GET pentru a prelua datele JSON de pe server, astfel inițiindu-se și parametrii care ascultă în caz că cererea a fost efectuată cu success sau eroare. Astfel în cazul primirii unui răspuns de success se returnează un parametru JSONArray cu datele adresei accesate, iar în cazul că a fost primită o eroare se returnează cauza erorii.

În aplicațiia Android la fel ca și pe platforma iOS se utilizează closures, doar că la Android ele se numesc callback-uri. Pentru aceste callback-uri se implementează o interfață aparte care are anumite metode ce reprezintă tipul răspunsului primit în timpul callbackului. Această interfață este prezentată în secvența următoare de cod, unde se pot observa metodele și parametrii acestora precum lista de automobile în cazul apelării metodei de success sau un mesaj de eroare în cazul primirii unei erori în timpul descărării datelor, acesta fiind afișat printr-un Toast.

public interface iCarListCallBack { void onDataParsed(List<CarCard> places); void onErrorResponse(VolleyError volleyError);

}

Pentru parsarea obiectelor JSON se utilizează la fel Volley care are posibilitatea de a extrage cu ușurință datele din JSON-ul primit. Acesta inițializează datele primite într-un obiect de tip JSON care este automat transformat într-un obiect înțeles de către program. Din acest obiect se pot extrage câmpurile necesare în tipul necesar.

List<CarCard> cars = new ArrayList<>(); for (int i = 0; i < response.length(); i++) { try {

JSONObject obj = response.getJSONObject(i);

String id = obj.getString("slug");

String name = obj.getString("offer");

String price = obj.getString("price");

String image = URL.getImageURL(obj.getJSONArray("carImages").getJSONObject(0).getString("name")); cars.add(new CarCard(id, name, price, image)); } catch (JSONException e) {

e.printStackTrace();

} }

carListCallBack.onDataParsed(cars);

În secvența de cod anterioară se poate observa cum se preia lista de automobile, în acest caz se creează o listă de obiecte de tip CarCard, aceasta fiind vidă. La prelucrarea datelor JSON primite se preia lista de obiecte ce conține acest obiect primit și este transformat în obiecte de tip CarCard, extrăgând doar câmpurile id, nume, preț și imagine. În cazul descărcării imaginii, de la server se recepționează doar denumirea acesteia, iar adresa de descărcare a imaginii este creată în urma prelucrării și adăugării adresei url necesare. Asta se face pentru a ușura inițializarea cardurilor cu automobile.

APIClient.getRecentCarList(currentPage, new APIClient.iCarListCallBack() {

@Override

public void onDataParsed(List<CarCard> cars) { loadFirstPage(cars);

}

@Override

public void onErrorResponse(VolleyError volleyError) {

Log.d("Main", volleyError.toString());

Toast.makeText(getApplicationContext(), "Error!", Toast.LENGTH_SHORT).show();

}

});

În secvența de cod precedentă este afișată apelarea APIClient pentru descărcarea listei de automobile recente, astfel se paote observa metodele callback care sunt apelate în cazurile date, în caz că datele sunt primite cu success atunci se încarcă în RecyclerView cardurile cu aceste autmobile. Imaginile acesteia fiind descărcate asincron și în ordinea apariției lor. Iar în caz că este o eroare aceasta se introduce în log și se afișează un Toast care să avertizeze utilizatorul că a apărut o eroare.

Punctul forte al aplicației este utlizarea plăților online. Astfel la vizualizarea unui automobil în bara de navigare este prezent un buton care reprezintă accesarea meniului de închiriere a automobilului. La apăsarea acestui buton se deschide pagina de completare a formularului pentru a încheia un contract de chirie cu compania de chirie și pentru efectuarea plății, acesta fiind afișat în figura 3.20.

Efectuarea plăților electronice se efectuează cu ajutorul sistemului de plăți online PayPal ce oferă o interfață simpă și necesită doar datele necesare și disponibile unui utilizator simplu precum ar fi numele și datele cardului bancar. Pentru introducerea acestor date PayPal oferă o fereastră simplă și care utilizează o conexiune securizată direct cu serverele PayPal pentru a asigura utilizatorii că transferul bancar va ajunge la destinație ci nu va fi fraudat, acestea fiind asigurate de către compania PayPal. Acest formular de plată este afișat indiferent de dispozitivul utilizat, fie Android sau iOS, este afișat și creată o sesiune de plată specială pentru transferuri de plăți.

Figura 3.20 – Formularul de închiriere a unui automobil

Cât pe platforma iOS dar și pe Android se utilizează formularul WEB pentru a efectua plata online și închirierea automobilului. Se utilizează acest mod de completare pentru a oferi o siguranță în efectuarea tranzacțiilor deoarece se utilizează protocolul https și datele personale sunt criptate și protejate.

UIApplication.shared.open(URL(string: (carDetails?.carRentLink)!)! , options: [:], completionHandler: nil)

În codul afișat mai sus se poate observa acțiunea care se efectuează în sistemul iOS la apăsarea butonului de chirie a automobilului. Iar mai jos este secvența de cod pentru sistemele Android.

Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(URL.getRentLink(carID))); startActivity(browserIntent);

Astfel se poate observa în secvențele anterioare că se creează un link special de chirie a automobilului, și este deschis în navigatorul web al dispozitivului, fără a impune utilizatorul să acceseze iarăși pagina web și să caute automobilul, lui fiindul oferit deodată formularul de finisare a chiriei.

4 Documentarea produsului realizat

Aplicația GulfCars este destinată utilizatorilor din Emiratele Arabe Unite, dar este posibilitatea de a adăuga și alte orașe. Aplicația poate fi utilizată de oricine, chiar și de persoanele de peste hotare care o pot descărca de pe magazinul Google Play sau AppStore, ea fiind disponibilă în toate țările, asta în caz că turșitii vin în Emiratele Arabe Unite și caută un mijloc de transport pe o anumită perioadă, anume un automobil, dar utilizatorii au setat în magazin o țară diferită de Emiratele Arabe Unite, asta reprezintă un avantaj pentru aplicație.

Magazin AppStore este magazinul aplicațiilor pentru dispozitivele Apple, iar aplicațiile sunt divizate pe categorii, și posibilități de descărcare pe iPhone sau iPad. Aplicația GulfCars aparține categoriei de Business și poate fi găsită prin accesarea meniului de căutare în magazin și anume prin căutarea aplicație „GulfCars”. În urma căutării se afișează aplicația pe magazin(figura 4.1) care paote fi descărcată fără taxe adiționale, aceasta fiind o aplicație gratuită pentru oricine.

Figura 4.1 – Aplicația GulfCars pe AppStore

Magazinul Google Play este magazinul aplicațiilor pentru dispozitivele ce rulează pe platforma Android. Aici sunt o mulțime de aplicații, chiar mai multe ca pe AppStore. La fel ca pe AppStore aplicațiile sunt divizate pe categorii, iar plicația GulfCars este în categoria Business. Pentru a găsi aplicația se caută în magazin introducând în bara de căutare „GulfCars” care returnează aplicația dată. La fel ca pe AppStore aplicația este oferită gratis tuturor utilizatorilor și nu include taxe adiționale în interiorul acesteia. La accesarea aplicației se deschide pagina cu detalii a acesteia(figura 4.2) și posibilitatea de descărcare a acesteia.

Figura 4.2 – Aplicația GulfCars pe magazinul Google Play

După descărcarea aplicației pe dispozitiv apare aplicația ce are ca iconiță logo-ul platoformei GulfCars. Aceasta fiind poziționată pe meniul principal pe dispozitivele iOS sau pe ecranul principal sau în meniu pe dispozitivele Android. Aceste aplicații pot fi văzute în figura 4.3 pe ambele platforme.

iOS Android

Figura 4.3 – Iconițele aplicațiilor pe platforma iOS și Android

La accesarea iconițelor se deschide aplicația GulfCars însăși, aceasta oferind un design simplist și plăcut, dar în primul și în primul rând un design unic pe ambele platforme, astfle încât să nu difere de la o platformă la alta.

La deschiderea aplicației se afilșează pagina principală a aplicației ce cuprinde o listă de automobile recent adăugate. Această liste este derulabilă și sunt încărcate tot mai multe automobile la derularea în jos. În bara de navigare sunt incluse butoanele de căutare și de sortare a automobilelor. La accesarea butonului de sortare se deschide un meniu dropdown unde se poate selecta una din opțiunile de sortare după automobilele recent apărute, automobilele sortate după preț crescător sau descrescător. Această paginp poate fi vizualizată în figura 4.4.

Figura 4.4 – Pagina principală a aplicației

La accesarea butonului de căutare apare pagina de căutare cu un câmp destinat introducerii denumirii automobilelor căutate, iar în urma căutării se afișează lista de automobile găsite după preferințele utilizatorului. Astfel în figura 4.5 este prezentată pagina cu rezultatele căutării automobilelor de marcă „BMW”, iar ca rezultat se afișează lista ce conține doar un singur automobil de marcă BMW, deoarece în baza de date este doar un singur automobil de acest tip.

Figura 4.5 – Rezultatele căutării automobilelor de marcă „BMW”

La accesarea unui automobil din listă se afișează pagina cu detalii a acestuia, care este afișată în figura 4.6, unde sunt afișate imaginile automobilului prezentate într-un slideshow, iar mai jos sunt deja detaliile tehnice a acestuia precum ar fi brand-ul, modelul, culoarea, distanța parcursă, anul producerii, descrierea oferita de către companie în privința automobilului și locația acestuia afișată pe Hărțile Google în partea de jos a paginii.

Figura 4.6 – Detaliile unui automobil

La accesarea unuia dintre butoanele de contactare a companiei în privința automobilului deschide ferestrele necesare în caz că se trimite un mesaj text sau a unui email către companie, iar în cazul apelului se efectuează un apel către companie. Aceste ferestre

În pagina de detalii a automobilului este prezent și câmpul de accesare a companiei ce oferă acest automobil în chirie. La accesarea acestui câmp se afișează pagina cu detalii a acesteia(figura 4.8), unde sunt indicate logoul companiei, orele de lucru, datele de contact asemănătoare ca și la detaliile automobilului, se deschid aplicațiile necesare pentru a trimite mesaj, email sau apelarea telefonică. Această pagină conține la fel o hartă pentru afișarea locației oficiului companiei, care este preluată de Hărțile Google.

Figura 4.8 – Detaliile companiei de chirie

Pagina de detalii a companiei conține un câmp pentru afișarea tuturor automobilelor oferite de către companie. Astfel la accesarea acestuia se deschide altă pagină unde este afișată o listă de automobile disponibile(figura 4.9), care la accesarea unuia dintre automobile deschide detaliile acestuia.

Figura 4.9 – Automobilele companiei

Pentru un design cât mai simplist se utilizează la fel aceeași aranjare a automobilelor după data adăugării și același design ca pe pagina principală unde este afișată o imagine a automobilului, denumirea acestuia dar și prețul acestuia pentru chirie. Iar la accesarea unui automobil se deschide aceeași pagină de detalii doar că fără posibilitatea de a accesa detaliile companiei ce oferă acest automobil în chirie.

5 Evaluarea economică a proiectului

Platforma de închiriere auto GulfCars face parte din categoria produselor cu scop comercial.

Scopul realizării proeictului este crearea unei platforme unice ce ar uni la un loc companiile ce propun acest tip de servicii de chirie a automobilelor prin utilizarea tehnologiilor noi de dezvoltare și care ar reduce numărul presonalului care trebuie să facă o parte din acest lucru manual și care ar eficientiza tranzacțiile bancare mult mai simplu. Odată ce platforma va fi utilizată, companiile vor putea să se înregistreze și să publice automobilele sale pe platformă ca utilizatorii să poată găsi mult mai simplu automobilele necesare. Pe piață există platforme asemănătoare, care sunt utilizate în cadrul căutării unui automobil, dar care nu dispun de funcționalul oferit de platforma Gulfcars, fie utilizează un sistem de înregistrare pentru a accesa automobilele disponibile sau nu dispun de o metodă de plată online și posibilitatea de închiriere este limitată sau nu sunt disponibile în anumite regiuni, fiind limitate doar pe anumite țări sau orașe.

Platforma de închiriere auto GulfCars este necesară pentru optimizarea căutării unui automobil de către utilizator, astfel excluzînd căutarea automobilelor pe paginile tuturor companiilor ce oferă acest serviciu, unificând aceste companii într-o singură platformă ce presupune accesarea tuturor automobilelor oferite de companiile înregistrate pe platformă. Astfel utilizatorul cu ușurință găsește ce are nevoie economisind timp prețios.

Este necesară implementarea acestei platforme pentru ușurarea căutării unui automobil , fiind un sistem actual și util. Deoarece suntem în secolul tehnologiilor informaționale, este necesar ca lucrurile să fie automatizate, pentru a ușura lucrul utilizatorilor, astfel reducând timpul de căutare a unui automobil cât mai mult, dar și posibilitatea de închiriere a acestuia și oferind posibilitatea de achitare online, excluzând rândurile și întârzierile, totul fiind transferat în mediul online direct de pe cardul bancar. Platforma de închiriere GulfCars este mult mai simplu de utilizat pentru utilizatori, oferind acestora o interfață grafică simplistă și ușor de utilizat, ceea ce face navigarea acestuia mult mai plăcută și fără eforturi sau cunoștințe adiționale în exploatarea acesteia cât pentru utilizatori dar și pentru companiile ce utilizează această platformă și încarcă automobilele sale pe platformă.

Utilizatorii platformei sunt însăși utilizatorii aplicațiilor mobile dar și utilizatorii aplicației web prin accesarea paginii web a platformei. Astfel aplicațiile fiind disponibile pentru descărcare gratuită de pe magazinele Google Play și AppStore. Interfața aplicațiilor fiind una simplă și intuitivă, astfel încât orice persoană poate utiliza cu ușurință aplicația mobilă. La fel ca și aplicațiile mobile, interfața web este una simplistă ce oferă utilizatorilor informația necesară utilizând un design minimalist.

Companiile au un panou de control simplist, ce le oferă acces la funționalitatea necesară acestora și excluzând setările inutile care sunt disponibile pe alte platforme, acestora fiindu-le oferite acces la lista lor de automobile, datele personale și atât. Pe lângă companii și utilizatori mai sunt și administratorii ce dirijează funcționalitatea platformei, dar și verifică automobilele și companiile ce sunt adăugate pe platformă, oferind utilizatorilor doar automobile verificate și sigure pentru închiriere.

5.1 Planul calendaristic

Obiectivele

Obiectivele principale ale proiectului:

crearea unui sistem, care are în componență o aplicație web și aplicație mobilă pe platformele Android și iOS;

dezvoltarea unei platforme online de închiriere auto;

dezvoltarea panoului de control;

asigurarea securității și confidențialității datelor; – și altele.

Evaluarea nivelului de lucru

Etapa de pregătire [10.09.2017 – 22.12.2017]:

primirea sarcinii;

cercetarea domeniului de lucru;

analiza sistemului actual;

elaborarea funcționalităților noi și eliminarea celor inutile; – cercetarea materialului didactic necesar.

Etapa de elaborare [01.02.2018 – 31.03.2018]:

descrierea amănunțită a platformei care urmează a fi creată;

elaborarea caietului de sarcini;

proiectarea platformei;

compararea platformei cu alte produse pe piață.

Etapa de finisare [01.04.2018 – 20.05.2018]:

crearea bazei de date de simulare;

crearea design-ului proiectului;

dezvoltarea modulelor; – integrarea modulelor; – testarea sistemului.

În tabelul 5.1 este reprezentat planul calendaristic de realizare a platformei GCR. Unitatea de măsură este ora, ceea ce reprezintă durata totală de lucru asupra unei anumite acțiuni.

Tabelul 5.1 – Planul calendaristic

Continuare Tabelul 5.1

5.2 Analiza SWOT

Pentru a concluziona dacă un sistem este rentabil sau nu, este necesar de făcut analiza SWOT precum este realizat în tabelul 5.2

Măsuri organizaționale de diminuare a riscurilor:

– crearea unei oferte avantajoase companiilor ce vor beneficia de platformă, făcând o investiție în crearea sistemului, vor beneficia de înregistrare gratuită în sistem; – introducerea unei taxe lunare de înregistrare pe platformă la un preț avantajos, – expedierea cererilor de acces la informația despre automobile la adrministrație și expunerea propunerilor de îmbunătățire a platformei.

Tabelul 5.2 – Analiza SWOT a platformei GCR

5.3 Calculul indicilor economici

Active materiale și nemateriale pe termen lung

În cadrul realizării platformei GCR, sa-u utilizat resurse sub forma de active materiale sau nemateriale pe termen lung. Acesta este indicat în tabelul 5.3.

Tabelul 5.3 – Active materiane și nemateriale pe termen lung

Consumuri directe de material

Consumuri directe de materiale – reprezintă valoarea materialelor, utilizate în procesul de producție incluse în costul produselor finite: elemente cu caracter material, utilizarea cărora este necesară în proiect, conform tabelului 5.4. Tabelul 5.4 – Consumuri directe

Cheltuieli directe pentru retribuirea muncii Cerințele către personal:

Programator: Tehnologii moderne de programare; limbaje de programare (Java, JS, NodeJS, Swift, altele); metode de lucru în echipă; tehnologii de programare și administrare a bazelor de date; șabloane de proiectare Software; elaborarea softului pentru platformele mobile (Android, iOS); elaborarea aplicațiilor web; cunoștințe în rețialistică; tehnologii moderne de securitate, si altele.

Administrator de BD: cunoștinte profunde în SQL și Oracle, tehnologii de programare și administrare a bazelor de date; cunoștințe în rețialistică; tehnologii moderne de securitate.

Designer: cunoștințe avansate în Photoshop și alte aplicații de modelare, cunoștințe în domeniul culorilor, și altele.

Team Lead: Tehnologii moderne de programare; limbaje de programare (C, C++, C#, Java, JS, Swift, altele); metode de lucru în echipă; tehnologii de programare și administrare a bazelor de date; șabloane de proiectare Software; elaborarea softului pentru platformele mobile (Android, iOS); elaborarea aplicațiilor web; cunoștințe în rețialistică; tehnologii moderne de securitate, modalități de organizare a lucrului în echipă, cunoștințe bune în limba engleză.

QA inginer : cunoștinte în limba engleză, toate metodele de testare a produsului program, cunoștițe în lucrul cu baza de date, etc.

Tabelul 5.5 cuprinde datele calculului cheltuielilor directe pentru redistribuirea muncii conform funcției angajatului si volumului de ore lucrate.

Tabelul 5.5 – Calculul cheltuielilor directe pentru reditribuirea muncii

Conform datelor din tabelul 5.5, pentru remunerarea muncii au fost cheltuite 32 395 lei. Totalul reprezintă Frm – Fondul de Retribuire a Muncii, în baza căruia se calculează suma contribuțiilor în Fondul Social (FS) – 23 % și valoarea primei de asigurare medicala obligatorie (AM) – 4,5%.

FAS = FRM × Cfs(%) (5.1)

unde:

FAS- Fondul de Asigurari Sociale,

FRM- Fondul de Retribuire a Muncii ,

Cfs – cota contribuțiilor de asigurări sociale de stat obligatorii, se aprobă în fiecare an prin Legea Bugetului asigurărilor sociale de stat. Conform „Legii bugetului asigurarilor sociale de stat pe anul 2018” contribuția la bugetul asigurărilor sociale de stat obligatorii, suportată de angajator, constituie 23% din fondul de remunerare a muncii.

FAM = FRM × Cam(%) (5.2)

unde:

FAM – fondurile asigurării obligatorii de asistență medicală;

Cam – Cota primei de asigurare obligatorie de asistență medicală, se aprobă în fiecare an prin Legea Republicii Moldova „Privind fondurile asigurării obligatorii de asistență medicală”. Conform „Legii privind fondurile asigurării obligatorii de asistență medicală pe anul 2018”, cota primei de asigurare obligatorie de asistență medicală suportata de angajator constituie 4,5 % din fondul de remunerare a muncii.

FAS = 32395,00 × 23% = 7450,85 lei (5.1`)

FAM = 32395,00 × 4,5% = 1457,77 lei (5.2`)

La final calculăm fondul de remunerare a muncii total pentru a cheltuielile necesare proiectului pentru salarizare.

FRMT = FRM + FAS + FAM (5.3) FRMT=32355,00 +7441,65+1455,97=41303,62 lei (5.3’)

Astfel utilizând prevederile legislației în vigoare vom calcula venitul net anual și respectiv suma impozitului pe venit transferat la bugetul de stat, cât și reținerile în fondul social și contribuțiile de asigurări medicale achitate de angajat.

Presupunem că venitul brut anual al programatorului este de 80 320 lei.

Calculăm reținerile în fondul pensionar (FP) și contributii asigurari medicale (FAM): FP = 6% × 80320 =4819,2 lei, FAM = 4,5% × 80320 = 3614,4 lei.

Calculul venitului impozabil:

VI = VB – FP – FAM – SP – SiP – SM (5.4)

unde:

VI – venitul impozabil;

VB – venitul brut;

FP – fondul de pensionare (asigurari sociale);

FAM – fondul de Asigurare Medicală;

SP – scutirea personală;

SiP – scutirea pentru persoana intreținută; SM – scutirea personală majoră.

Folosind formula (5.4) se efectuează calculele pentru determinarea venitului impozabil:

VI = 80320 – 4819,2 – 3614,4 – 11280 = 60606,4 lei.

Se calculează suma impozitului pe venit:

IV = VI – I (5.5)

unde:

I – cota de impozitare a persoanei fizice.

IV = 33000 × 7%+(60606,4 – 33000) ×18%=2310+4969,15 = 7 279,15 lei.

Se calculează suma venitului net aplicând cotele de impozitare în vigoare:

VN = VB – IV – FP – FAM (5.6)

unde:

VN- venitul net;

VB – venitul brut;

IV – impozit pe venit;

FP – fondul de pensionare (asigurari sociale);

FAM – prima de Asigurare Medicală;

VN = 80320 – 7279,15 – 4819,2 – 3614,4 = 64 607,25 lei.

5.4 Consumuri indirecte

Pentru realizarea acestui proiect au fost utilizate și consumuri indirecte. Conform tabelului 5.6, pe perioada realizării acestui proiect au fost achitate arenda încăperii și serviciile internet. Aceste consumuri indirecte au fost utilizate timp de 4 luni.

Tabelul 5.6 – Consumuri indirecte

5.5 Uzura mijloacelor fixe și amortizarea activelor nemateriale pe termen lung

Uzura mijloacelor fixe reprezintă repartizarea sistematică a valorii uzurabile a mijloacelor fixe în decursul duratei de funcționare utilă. Norma uzurii se calculează în dependență de durata utilizării activului. Durata utilizării activului se determină după categoria lui. AMTL – 3-5 ani, ANTL – 2-3 ani.

FA = MFi : DFU × T1 (5.7)

unde:

FA – fondul amortizarii, lei;

MFi – valoarea de intrare;

T1 – durata proiectului;

DFU – durata de funcționare utilă .

Uzura activelor nemateriale cu termen lung de utilizare se va calcula pentru fiecare mijloc fix conform metodei casării lunare. Astfel fondul de amortizare pentru iMac, PC și Telefonul folosit în cadrul elaborării proiectului calculate conform formulei (5.7) este:

Calcularea fondului de amortizare pentru Enterpise Architect, Microsoft Word și Adobe Photoshop CC folosite în cadrul elaborării proiectului:

Astfel fondul de amortizare pentru mijloacele fixe folosite în cadrul elaborării proiectului sunt:

5.6 Costul de producție

Costul de producție reprezintă totalitatea cheltuielilor, corespunzătoare consumului de factori de producție, pe care agenții economici le efectuează pentru producerea și vânzarea de bunuri materiale sau prestarea de servicii. Prețul de cost se calculează pe o unitate, conform tabelului 5.7. Dacă se elaborează o pagină web sau o aplicație, atunci va fi prețul de cost al elaborării, dar dacă în cadrul proiectului se planifică multiplicarea produsului, atunci este nevoie de calculat costul de elaborare al unei copii.

Tabel 5.7 – Costul de producție

Concluzii

Chiria de automobile se dezvoltă pe scară largă în zilele cotidiene și găsirea cât mai rapidă și eficientă în zilele noastre este o deficiență majoră, deoarece mută lume nu găsește ceea ce are nevoie sau cade capcană diferitor înșelăciuni, astfel am ajuns la concluzia de a crea o platformă simplă și disponibilă tuturor ce unește toate companiile de chirie de automobile din regiune la un singur loc și evitarea fraudelor în domeniul dat. Astfel platforma dată satisface atât necesitățile utilizatorului de a închiria o mașină la un preț accesibil de la un dealer verificat, cu actele în regulă și mașini verificate, cu opțiunea de a achita online și de a nu sta în rând la oficii pentru a închiria un automobil.

În timpul realizării platformei GCR am atras atenția la proiectarea sistemului, deoarece în urma proiectări bine structurate a caietului de sarcini ce constituie fundamentul proiectului, iar pentru un proiect de succes este necesar ca proiectarea acestuia să fie bine întocmită.

La proiectarea sistemului s-au utilizat anume diagramele UML, astfel pentru Platforma GCR am determinat că diagramele cazurilor de utilizare sunt diagramele UML utilizate pentru a oferi o imagine de ansamblu asupra comportamentului funcțional al unui sistem software. Astfel am descris modul în care un utilizator poate interacționa cu aplicația mobilă, am specificat clasele ce vor constitui structura acesteia în timpul implimentării aplicației, iar diagramele de componente și de amplasare împreună cu diagramele de clasă descriu modul în care are loc interacțiune dintre clase și sistemul însăși.

În cadrul implementării aplicațiilor mobile a fost utlizat modelul arhitectural MVC, pentru o structurare mult mai simplă a codului și divizarea acestora pe componente mai mari precum ar fi modelele, controllerele și interfața utilizatorului. Pentru realizarea conexiunii cu serverul se utilizează module speciale care transmit și preiau datele de pe server prin cererile HTTP, iar datele primite fiind in format JSON sunt prelucrate și transformate în modele care apoi sunt trimise spre controller care le prelucrează și le încarcă în interfața grafică.

În urma efectuării analizei economice am ajuns la concluzia că fiecare aplicație are un anumit preț, iar în cazul dat prețul pentru implementarea acesteia se calculează în dependență de numărul de ore lucrate pentru a putea primi un preț real pentru dezvoltarea aplicației.

Platforma GCR reprezintă un sistem informatic complex, fiind o platformă cu o interfață de lucru intuitivă și prietenoasă, ce cred că va fi de mare ajutor utilizatorilor ce își doresc să închirieze un autoturism sigur și rapid.

Bibliografie

1 Car rental system [Resursă electronică]. – Regim de access: https://www.slideshare.net/itskevin12/car-rental-system-54772748 2 Sistem informațional [Resursă electronică]. – Regim de access:

http://www.zota.ase.ro/simp/Sistem%20informational.pdf

Enterprise Architect [Resursă electronică]. – Regim de access:

http://www.sparxsystems.com/products/ea/

What is Unified Modeling Language (UML)? [Resursă electronică]. – Regim de access: https://www.visual-paradigm.com/guide/uml-unified-modelinglanguage/what-is-uml/

Modelarea Cazurilor de Utilizare [Resursă electronică]. – Regim de access:

http://inf.ucv.ro/~mihaiug/courses/is/lab/lab3-4.pdf

Laborator 01. Introducere în Programarea Android [Resursă electronică]. – Regim de access: https://ocw.cs.pub.ro/courses/eim/laboratoare/laborator01 7 Android software development [Resursă electronică]. – Regim de access:

http://www3.ul.ie/ictlc/Android.pdf

Despre Swift – limbajul de programare dezvoltat de Apple [Resursă electronică]. – Regim de access: https://www.fasttrackit.org/despre-swift-limbajulde-programare-dezvoltat-de-apple/

Introducere in Desig Patterns – MVC [Resursă electronică]. – Regim de access:

http://www.worldit.info/articole/introducere-in-design-patterns-mvc-partea-i/ 10 Storyboards Tutorial for iOS: Part 1 [Resursă electronică]. – Regim de access:

https://www.raywenderlich.com/160521/storyboards-tutorial-ios-11-part-1

What is a storyboard? [Resursă electronică]. – Regim de access: https://www.hackingwithswift.com/example-code/language/what-is-a-storyboard

Closures [Resursă electronică]. – Regim de access:

https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_ Programming_Language/Closures.html

Anexa A

Codul sursă pentru aplicația iOS

class MainViewController: UITableViewController { var cars = [CarCard]() var selectedFilter = 0 var currentPage = 0 var maxCarsShowed = 50 var requestedCarID = "" var reachability: Reachability?

@IBOutlet weak var loadingSpinner: UIActivityIndicatorView!

override func viewDidLoad() { super.viewDidLoad() HUD.show(.progress)

self.view.backgroundColor = AppColors.background

self.refreshControl?.addTarget(self, action: #selector(doRefresh(refreshControl:)), for: .valueChanged)

setupReachabilityGetData(nil, useClosures: true) startNotifier()

}

func startDownloadingData() {

APIClient.getRecentCarList(page: currentPage, success: { (data) in self.cars = data

self.maxCarsShowed = data.count self.tableView.reloadData()

HUD.hide()

}, failure: { _ in

HUD.flash(.labeledError(title: "", subtitle: "Error!"), delay: 2.0)

})

}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

return cars.count

}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "mainViewCell", for:

indexPath) as! MainTableViewCell

if indexPath.row == cars.count-1, indexPath.row < maxCarsShowed – 1 { loadingSpinner.startAnimating() DispatchQueue.main.async {

self.downloadData(status: self.selectedFilter, page: (self.currentPage + 1), success: { (data) in

self.cars.append(contentsOf: data) self.currentPage += 1 self.tableView.reloadData()

}, failure: { (error) in

HUD.flash(.labeledError(title: "", subtitle: error), delay: 2.0) self.loadingSpinner.stopAnimating()

})

} } else {

loadingSpinner.stopAnimating()

}

cell.prepare(data: cars[indexPath.row]) return cell

}

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { tableView.deselectRow(at: indexPath, animated: true)

let selectedCell:UITableViewCell = tableView.cellForRow(at: indexPath as IndexPath)!

requestedCarID = cars[indexPath.row].getCarID()

performSegue(withIdentifier: "mainViewCarDetailsSegue", sender: selectedCell)

}

override func prepare(for segue: UIStoryboardSegue, sender: Any?) { let backItem = UIBarButtonItem() backItem.title = " "

navigationItem.backBarButtonItem = backItem

if segue.identifier == "mainViewCarDetailsSegue" { let newVC : CarDetailsViewController = (segue.destination as?

CarDetailsViewController)!

newVC.carID = requestedCarID

}

} func downloadData(status: Int, page: Int, success: @escaping ([CarCard]) -> Void, failure:

@escaping (String) -> Void) { switch(status) { case 0 : maxCarsShowed = 50

APIClient.getRecentCarList(page: page, success: { (data) in success(data)

self.maxCarsShowed = data.count

}, failure: { (error) in failure(error)

}) break; case 1:

maxCarsShowed = 200

APIClient.getAscendingCarList(page: page, success: { (data) in success(data)

self.maxCarsShowed = data.count

}, failure: { (error) in failure(error)

}) break; case 2:

maxCarsShowed = 200

APIClient.getDescendingCarList(page: page, success: { (data) in success(data)

self.maxCarsShowed = data.count

}, failure: { (error) in failure(error)

}) break; default: break;

} }

func askToConnectInternet(){ HUD.hide()

let alert = UIAlertController(title: "Cellular Data is Turned Off", message: "Turn on cellular data or use Wi-Fi to access data.", preferredStyle: UIAlertControllerStyle.alert) alert.addAction(UIAlertAction(title: "Settings", style: UIAlertActionStyle.default, handler: openSettings)) alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: nil))

DispatchQueue.main.async {

self.present(alert, animated: true, completion: nil)

}

}

func openSettings(alert: UIAlertAction!) {

UIApplication.shared.open(URL(string: "App-Prefs:root")!, options: [:], completionHandler: nil)

}

}

class APIClient {

public static func getRecentCarList(page : Int,

success: @escaping (_ data: [CarCard]) -> Void, failure: @escaping (_ error: String) -> Void) { getCarList(url: URLAdress.carList, page: page, success: { (data) in success(data) }, failure: { (error) in failure(error)

})

}

public static func getAscendingCarList(page : Int,

success: @escaping (_ data: [CarCard]) -> Void, failure: @escaping (_ error: String) -> Void) { getCarList(url: "\(URLAdress.carList)?order=price&by=ASC", page: page, success:

{ (data) in

success(data) }, failure: { (error) in failure(error)

})

}

public static func getDescendingCarList(page : Int,

success: @escaping (_ data: [CarCard]) -> Void, failure: @escaping (_ error: String) -> Void) { getCarList(url: "\(URLAdress.carList)?order=price&by=DESC", page: page, success:

{ (data) in

success(data) }, failure: { (error) in failure(error)

})

}

public static func getSearchRecentCarList(phrase: String, page : Int, success: @escaping (_ cars: Int, _ data:

[CarCard]) -> Void,

failure: @escaping (_ error: String) -> Void) { getCarList(url: URLAdress.getSearchCarList(search: phrase), page: page, success:

{ (data) in

success(data.count, data) }, failure: { (error) in failure(error)

})

}

public static func getSearchAscendingCarList(phrase: String, page : Int, success: @escaping (_ cars: Int, _ data:

[CarCard]) -> Void,

failure: @escaping (_ error: String) -> Void)

{

getCarList(url: "\(URLAdress.getSearchCarList(search: phrase))&order=price&by=ASC", page: page, success: { (data) in success(data.count, data) }, failure: { (error) in failure(error)

})

}

public static func getSearchDescendingCarList(phrase: String, page : Int, success: @escaping (_ cars: Int, _ data:

[CarCard]) -> Void,

failure: @escaping (_ error: String) -> Void)

{

getCarList(url: "\(URLAdress.getSearchCarList(search: phrase))&order=price&by=DESC", page: page, success: { (data) in success(data.count, data) }, failure: { (error) in failure(error)

})

}

public static func getCarDealerCarList(dealerID : String, page : Int,

success: @escaping (_ cars: Int, _ data: [CarCard])

-> Void,

failure: @escaping (_ error: String) -> Void) {

}

public static func getCarDetails(id : String,

success: @escaping (_ data: CarDetails) -> Void, failure: @escaping (_ error: String) -> Void) { Alamofire.request(URLAdress.getCarDetails(car: id)).responseJSON { (response) in if(response.result.isSuccess) {

if((response.response?.statusCode)! == 200) { let data = JSON(data: response.data!) var carImages = [String]()

let jsonArr = data["carImages"].arrayValue for image in jsonArr { carImages.append(URLAdress.getImageURL(image: image["name"].stringValue)) }

let carDetails = CarDetails(id: data["slug"].stringValue, name: data["offer"].stringValue, price: data["price"].stringValue, rentLink: URLAdress.getRentLink(carID:

data["slug"].stringValue),

images: carImages, messageNumber:

data["company.phone"].stringValue,

callNumber: data["company.phone"].stringValue, email: data["company.users.email"].stringValue,

description: data["description"].stringValue, detailsBrand: data["brand.name"].stringValue, detailsModel: data["model"].stringValue, detailsYear: data["year"].stringValue, detailsWheels: data["tireSize"].stringValue, detailsColor: data["color"].stringValue, detailsDistance:

data["kilometrage"].stringValue,

detailsSpecs: data["specs"].stringValue, detailsGearBox:

data["transmission"].stringValue,

detailsSeats: data["seats"].stringValue, detailsCylinders:

data["cylinders"].stringValue,

detailsInterior: data["interior"].stringValue, detailsCondition: data["condition"].stringValue, dealerImage: URL(string:

URLAdress.getCompanyImageURL(image: data["company.companyLogo"].stringValue))!,

dealerName: data["company.name"].stringValue, dealerID: data["company.slug"].stringValue, locationLatitude:

data["latitude"].doubleValue, locationLongitude: data["longitude"].doubleValue)

success(carDetails)

} else {

failure("Data not found!")

} } else {

failure("Connection error!")

}

}

}

public static func getCarDealer(id : String,

success: @escaping (_ data: CarDealer) -> Void, failure: @escaping (_ error: String) -> Void) {

Alamofire.request(URLAdress.getCompanyDetails(company: id)).responseJSON { (response) in

if(response.result.isSuccess) {

if((response.response?.statusCode)! == 200) { let data = JSON(data: response.data!)

let dealerDetails = CarDealer(id: data["slug"].stringValue, image: URL(string:

URLAdress.getCompanyImageURL(image: data["companyLogo"].stringValue))!, name: data["name"].stringValue, workingHours:

"\(data["openingHour"].stringValue) – \(data["closingHour"].stringValue)",

reviewsID: data["placeID"].stringValue, messageNumber: data["phone"].stringValue, callNumber: data["phone"].stringValue, email: data["users.email"].stringValue, description: data["address"].stringValue, locationLatitude:

data["latitude"].doubleValue, locationLongitude:

data["longitude"].doubleValue)

success(dealerDetails)

} else {

failure("Data not found!")

} } else {

failure("Connection error!")

}

}

}

public static func getBasicReviewDetails(id : String,

success: @escaping (_ data: BasicReviewDetails) -> Void, failure: @escaping (_ error: String) -> Void) {

Alamofire.request(URLAdress.getCompanyReviews(company: id)).responseJSON { (response) in

if(response.result.isSuccess) {

if((response.response?.statusCode)! == 200) { let data = JSON(data: response.data!) if !data["error_message"].stringValue.isEmpty { failure("Data nor found!")

} else {

if data["rating"].stringValue == "no rating" { failure("No reviews")

} else {

let basicReview = BasicReviewDetails(name: data["review"][0]["author_name"].stringValue, description:

data["review"][0]["text"].stringValue, stars: data["rating"].doubleValue)

success(basicReview)

}

} } else {

failure("Data not found!")

} } else {

failure("Connection error!")

}

}

}

}

Anexa B

Codul sursă pentru aplicația Android

public class CarDetailsActivity extends AppCompatActivity {

String carID = "";

CarDetails car = new CarDetails();

ViewPager viewPager;

CirclePageIndicator sliderDotspanel;

private String previousActivity = "otherActivity";

TextView carPrice;

ImageButton callButton;

ImageButton smsButton;

ImageButton emailButton;

TextView carDescription;

TextView carDetailsBrand;

TextView carDetailsModel;

TextView carDetailsYear;

TextView carDetailsWheels;

TextView carDetailsColor;

TextView carDetailsKilometers;

TextView carDetailsSpecs;

TextView carDetailsGearBox;

TextView carDetailsSeats;

TextView carDetailsCylinders;

TextView carDetailsInterior;

TextView carDetailsCondition;

CircleImageView carDealerLogo;

TextView carDealerName;

View carDealerView;

MapView mapView;

GoogleMap gMap;

LatLng position = new LatLng(car.carLocationLatitude, car.carLocationLongitude);

String markerText = car.carName;

@Override

protected void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState);

setContentView(R.layout.activity_car_details);

Intent intent = getIntent(); if (intent.hasExtra("activity")) {

previousActivity = intent.getStringExtra("activity"); if (intent.hasExtra("carID")) {

carID = intent.getStringExtra("carID");

} else {

Utility.showToast("Failed to get car info"); return;

} } else {

previousActivity = "otherActivity"; SavingInstance sv = new SavingInstance(); carID = sv.getPreference("carID");

previousActivity = sv.getPreference("activity");

}

Log.d("carID", carID);

Log.d("activity", previousActivity);

if (previousActivity.equals("carDealer")) {

ImageView image;

image = (ImageView) findViewById(R.id.carDealerArrow); image.setVisibility(View.INVISIBLE);

}

mapView = (MapView) this.findViewById(R.id.carDetailsMapView); mapView.onCreate(savedInstanceState);

APIClient.getCarDetails(carID, new APIClient.iCarDetailsCallback() {

@Override

public void onDataParsed(CarDetails carDetails) { car = carDetails; preparePage();

position = new LatLng(car.carLocationLatitude, car.carLocationLongitude); markerText = car.carName;

mapView.getMapAsync(new OnMapReadyCallback() {

@Override

public void onMapReady(GoogleMap googleMap) { gMap = googleMap;

Marker marker = gMap.addMarker(new

MarkerOptions().position(position).title(markerText));

CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(position,

16);

gMap.animateCamera(cameraUpdate);

}

});

}

@Override

public void onErrorResponse(VolleyError volleyError) {

Utility.showToast("Error!");

Log.d("CarDetailsActivity", volleyError.toString());

}

});

}

@Override

public void onSaveInstanceState(Bundle savedInstanceState) { super.onSaveInstanceState(savedInstanceState); SavingInstance sv = new SavingInstance(); sv.setPreference("carID", carID);

sv.setPreference("activity", previousActivity);

}

private View.OnClickListener carDealerListener = new View.OnClickListener() { public void onClick(View v) {

if (!previousActivity.equals("carDealer")) {

Intent intent = new Intent(CarDetailsActivity.this, CarDealerActivity.class); intent.putExtra("dealerID", car.carDealerID); startActivity(intent);

}

}

};

private View.OnClickListener callButtonPressed = new View.OnClickListener() { public void onClick(View v) {

Intent callIntent = new Intent(Intent.ACTION_DIAL); callIntent.setData(Uri.parse("tel:" + car.callNumber)); try {

startActivity(callIntent);

} catch (android.content.ActivityNotFoundException ex) {

Utility.showToast("Could not make the call.");

}

} };

private View.OnClickListener smsButtonPressed = new View.OnClickListener() { public void onClick(View v) {

Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("sms:" + car.messageNumber));

intent.putExtra("sms_body", "Hi! I'm interested in your " + car.carName +

" car, can I get more details about this car?"); try {

startActivity(intent);

} catch (android.content.ActivityNotFoundException ex) {

Utility.showToast("Could not send the SMS.");

}

} };

private View.OnClickListener emailButtonPressed = new View.OnClickListener() { public void onClick(View v) {

Intent i = new Intent(Intent.ACTION_SEND);

i.setType("message/rfc822");

i.putExtra(Intent.EXTRA_EMAIL, new String[]{car.email});

i.putExtra(Intent.EXTRA_SUBJECT, "Car rent – " + car.carName);

i.putExtra(Intent.EXTRA_TEXT, "Hi! I'm interested in your " + car.carName + " car, can I get more details about this car?"); try {

startActivity(Intent.createChooser(i, "Sending mail…"));

} catch (android.content.ActivityNotFoundException ex) {

Utility.showToast("Could not send the email.");

}

}

};

}

public class APIClient {

public static void getRecentCarList(Integer page, iCarListCallBack carListCallBack) { getCarList(URL.carList, page, carListCallBack);

}

public static void getAscendingCarList(Integer page, iCarListCallBack carListCallBack) { getCarList(URL.carList + "?order=price&by=ASC", page, carListCallBack); }

public static void getDescendingCarList(Integer page, iCarListCallBack carListCallBack) { getCarList(URL.carList + "?order=price&by=DESC", page, carListCallBack); }

public static void getSearchRecentCarlist(String phrase, Integer page, iCarListCallBack carListCallBack) {

getCarList(URL.getSearchCarList(phrase), page, carListCallBack); }

public static void getSearchAscendingCarlist(String phrase, Integer page, iCarListCallBack carListCallBack) {

getCarList(URL.getSearchCarList(phrase) + "&order=price&by=ASC", page, carListCallBack);

}

public static void getSearchDescendingCarlist(String phrase, Integer page, iCarListCallBack carListCallBack) {

getCarList(URL.getSearchCarList(phrase) + "&order=price&by=DESC", page, carListCallBack);

}

public static void getDealerCarList(String dealerID, Integer page, iCarListCallBack carListCallBack) {

getCarList(URL.getCompanyCarList(dealerID), page, carListCallBack); }

public static void getCarDetails(String id, final iCarDetailsCallback carDetailsCallback) { final RequestQueue requestQueue =

Volley.newRequestQueue(GulfCarsApplication.getAppContext());

JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, URL.getCarDetails(id), null,

new Response.Listener<JSONObject>() {

@Override

public void onResponse(JSONObject response) { CarDetails carDetails = new CarDetails(); try {

carDetails.carID = response.getString("slug"); carDetails.carName = response.getString("offer"); carDetails.carPrice = response.getString("price"); carDetails.carRentLink = URL.host;

ArrayList<String> images = new ArrayList<>();

for (int i = 0; i < response.getJSONArray("carImages").length(); i++) {

images.add(URL.getImageURL(response.getJSONArray("carImages").getJSONObject(i).getString("name ")));

} catch (JSONException e) {

e.printStackTrace(); }

carDetailsCallback.onDataParsed(carDetails);

}

}, new Response.ErrorListener() {

@Override

public void onErrorResponse(VolleyError error) { carDetailsCallback.onErrorResponse(error);

} });

requestQueue.add(jsonObjectRequest);

}

public static void getCarDealer(String id, final iCompanyDetailsCallback companyDetailsCallback) {

final RequestQueue requestQueue =

Volley.newRequestQueue(GulfCarsApplication.getAppContext());

JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, URL.getCompanyDetails(id), null,

new Response.Listener<JSONObject>() {

@Override

public void onResponse(JSONObject response) { CarDealer carDealer = new CarDealer(); try {

carDealer.dealerID = response.getString("slug");

carDealer.dealerImage =

URL.getCompanyImageURL(response.getString("companyLogo"));

carDealer.dealerName = response.getString("name");

carDealer.dealerWorkingHours = response.getString("openingHour") +

" – " + response.getString("closingHour");

carDealer.dealerReviewsID = response.getString("placeId"); carDealer.messageNumber = response.getString("phone"); carDealer.callNumber = response.getString("phone"); carDealer.email = response.getString("users.email"); carDealer.dealerDescription = response.getString("address");

carDealer.dealerLocationLatitude = response.getDouble("latitude"); carDealer.dealerLocationLongitude = response.getDouble("longitude");

} catch (JSONException e) {

e.printStackTrace(); }

companyDetailsCallback.onDataParsed(carDealer);

}

}, new Response.ErrorListener() {

@Override

public void onErrorResponse(VolleyError error) { companyDetailsCallback.onErrorResponse(error);

} });

requestQueue.add(jsonObjectRequest);

}

public static void getBasicReviewDetails(String id, final iBasicReviewCallback basicReviewCallback) {

final RequestQueue requestQueue =

Volley.newRequestQueue(GulfCarsApplication.getAppContext());

JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, URL.getCompanyReviews(id), null,

new Response.Listener<JSONObject>() {

@Override

public void onResponse(JSONObject response) {

BasicReviewDetail basicReviewDetail = new BasicReviewDetail(); try {

if (response.getString("rating").equals("no rating")) { basicReviewCallback.onErrorResponse(new VolleyError());

} else {

basicReviewDetail = new BasicReviewDetail(

response.getJSONArray("review").getJSONObject(0).getString("author_name"),

response.getJSONArray("review").getJSONObject(0).getString("text"), response.getDouble("rating")

);

basicReviewCallback.onDataParsed(basicReviewDetail);

}

} catch (JSONException e) {

e.printStackTrace();

}

}

}, new Response.ErrorListener() {

@Override

public void onErrorResponse(VolleyError error) { basicReviewCallback.onErrorResponse(error);

} });

requestQueue.add(jsonObjectRequest);

}

public interface iCarListCallBack {

void onDataParsed(List<CarCard> places);

void onErrorResponse(VolleyError volleyError);

}

public interface iCarDetailsCallback { void onDataParsed(CarDetails carDetails);

void onErrorResponse(VolleyError volleyError);

}

public interface iCompanyDetailsCallback { void onDataParsed(CarDealer carDealer);

void onErrorResponse(VolleyError volleyError);

}

public interface iBasicReviewCallback {

void onDataParsed(BasicReviewDetail reviews);

void onErrorResponse(VolleyError volleyError);

}

public interface iReviewListCallback {

void onDataParsed(List<ReviewCard> places);

void onErrorResponse(VolleyError volleyError);

}

}

Similar Posts