NSLocalizedString(Yes, nil) [308293]

UNIVERSITATEA DIN ORADEA

FACULTATEA DE INGINERIE ELECTRICĂ ȘI TEHNOLOGIA INFORMAȚIEI

PROGRAMUL DE STUDIU MANAGEMENT ÎN TEHNOLOGIA INFORMAȚIEI

FORMA DE ÎNVĂȚĂMÂNT ZI

Studiu comparativ:

Android vs. iOS

COORDONATOR ȘTIINȚIFIC:

Prof.univ.dr.ing. Cornelia Györödi

ABSOLVENT: [anonimizat]

2017

Capitolul I. Introducere

Tema acestui proiect îl reprezintă realizarea unei comparații în ceea ce privește implementarea a [anonimizat]. Aplicațiile sunt însoțite de o [anonimizat].

Principalul obiectiv imediat al platformei web este acela de a oferi o metodă alternativă de promovare a locațiilor de divertisment și de interes din cadrul unei regiuni geografice. Printr-o perspectivă care acoperă o [anonimizat] a [anonimizat]. Platforma permite promovarea în prealabil a evenimentelor corespunzătoare unei locații precum și adăugarea unor galerii descriptive pentru evenimentele anterioare.

În timp ce accentul cade pe promovare la o [anonimizat]. Cele două aplicații prezintă funcționalități identice și sunt optimizate pentru a respecta șabloanele de utilizare corespunzătoare sistemelor de operare pe care acestea rulează

Aplicațiile mobile permit accesul unificat la o listă de locații și evenimente viitoare din cadrul unei zone geografice. [anonimizat].

Pentru realizarea platformei sunt utilizate tehnologii de ultimă generație. Întregul proces de dezvoltare s-a axat în jurul platformei Laravel care implementează cele mai noi concepte pentru dezvoltarea de aplicații Web moderne.

[anonimizat] a fost elaborate folosind cele mai noi versiuni ale librăriilor și ale platformelor de dezvoltare software (Android Studio respectiv XCode) oferite de creatorii sistemelor de operare Android și iOS. Utilizarea metodelor si a limbajelor native a [anonimizat] a aplicației pe un număr cât mai mare de dispozitive mobile.

Astfel, platforma și aplicația complementară își propun să demonstreze viabilitatea dezvoltării de aplicații mobile native optimizate pentru cerințele specifice sistemelor de operare gazdă.

Capitolul II. Tehnologii utilizate

Limbajele și mediile de dezvoltare selectate pentru elaborarea acestui proiect reprezintă o consecință directă a faptului că aplicația este compusă din trei mari componente:

O componentă care rulează pe un server și prezintă o interfață accesibilă doar unei anumite categorii de utilizatori

O implementare care rulează pe dispozitive independente( terminale Android ) care este accesibilă tuturor utilizatorilor

O implementare construită pentru dispozitive care rulează pe sistemul de operare iOS și oferă o funcționalitate identică aplicației pentru Android

Această delegare a rolurilor a condus la implementări care se bazează pe un subset de limbaje diferite pentru a putea profita de beneficiile dezvoltării native pentru fiecare tip de sistem. Astfel procesul de dezvoltare s-a axat în jurul limbajelor PHP pentru aplicația server și Java, respectiv Objective C pentru aplicațiile client.

II.1. Tehnologii utilizate la nivelul de aplicației server

PHP (acronim recursiv pentru PHP: Hypertext Preprocessor) este un limbaj de scripting de uz general, cu cod-sursă deschis, utilizat pe scară largă, și care este potrivit în special pentru dezvoltarea aplicațiilor web și poate fi integrat în HTML.

PHP este o tehnologie pe partea de server, inter-platformă. Sintagma „pe parte de platformă” se referă la faptul că acțiunile unui script PHP sunt executate pe server, respectiv nu pe dispozitivul pe care rulează navigatorul web al utilizatorului ce vizitează site-ul Web. Natura inter-platformă a limbajului înseamnă că PHP rulează pe majoritatea sistemelor de operare, inclusiv pe Windows, Unix și Macintosh. PHP oferă performanțe excelente, integrare strânsă cu aproape orice bază de date existentă, stabilitate, portabilitate și un set aproape nelimitat de funcții, datorită extensiilor disponibile.

Versiunea cu numărul 5 a limbajului PHP, utilizată aici în cadrul procesul de implementare, reprezintă o dezvoltare majoră a acestui limbaj popular; una dintre modificările majore aduse se referă la programarea orientată pe obiecte.

Programarea orientată pe obiecte(POO) este o paradigmă de programare, axată pe ideea încapsulării, adică gruparea datelor și a codului care operează asupra lor, într-o singură structură. Un alt concept important asociat programării orientate obiect este polimorfismul, care facilitează abstractizări ce permit o descriere conceptuală mai simplă a soluției.

Interfațarea relativ simplă cu bazele de date alături de avantajele programării orientate pe obiecte și disponibilitatea inter-platformă reprezintă principalele motive pentru alegerea acestui limbaj ca bază pentru implementarea variantei server a aplicației.

MySQL este un sistem de gestionare a bazelor de date (DBMS – Database Management System) pentru baze de date relaționale(RDBMS – Relational Database Management System), produs de compania suedeza MySQL AB și distribuit sub Licența Publică Generală GNU. Este cel mai popular și argumentabil, cel mai bun sistem de gestiune a bazelor de date cu sursă deschisă la ora actuală, fiind o componentă cheie a stivei LAMP (Linux, Apache, MySQL, PHP).

În cadrul proiectului, MySQL versiunea 5 este utilizată pentru manipularea și stocarea datelor iar pentru interacțiunea la nivel de interfață s-a utilizat phpMyAdmin, un sistem de gestiune a bazelor de date, liber, destinat administrării bazelor de date prin intermediul unui navigator Web.

În timp ce PHP și MySQL sunt folosite pentru operațiunile care sunt transparente utilizatorului, pentru construcția interfeței și prezentarea informațiilor s-au utilizat HTML, CSS și JavaScript.

HTML (HyperText Markup Language) este un limbaj de marcare folosit de navigatoarele Web pentru a determina modul de afișare a conținutului paginilor Web. Elemente de bază ale HTML sunt o serie de câmpuri sau marcaje speciale, numite și tag-uri sau etichete HTML. O altă caracteristică esențială a HTML o constituie posibilitatea realizării de legături (link-uri sau hyperlink-uri) spre alte documente/pagini Web.

La momentul scrierii acestei lucrări, standardul HTML se află la a cincea sa revizuire. HTML5 aduce numeroase modificări la nivel sintactic prin introducerea de elemente noi( printre care <header>, <nav>, <section>, <article>, <nav>, <footer> ) sau prin alterarea unor elemente existente( <a>, <cite>, <meniu> ). În cadrul proiectului, s-a urmărit conformarea cu specificațiile HTML5 și evitarea elementelor depreciate pentru a asigura o funcționare în parametri normali pentru o perioada cât mai îndelungată.

Deși limbajul HTML stă la baza construcției interfețelor web, modificările care pot fi aduse aspectului acestor interfețe, în cadrul limbajului, sunt limitate.

Limbajul CSS este utilizat pentru îmbunătățirea prezentării paginilor Web. CSS este un acronim pentru Cascading Style Sheets( foi de stil în cascadă ). Acest limbaj are rolul unui instrument avansat destinat proiectării unor site-uri Web profesionale care nu pot fi construite folosind atribute HTML obișnuite.

Ultimul standard al limbajului (CSS3) a fost utilizat pentru dezvoltarea proiectului întrucât această revizie introduce și extinde funcționalitatea a numeroase stiluri (animații, borduri, efecte) care s-au dovedit a fi esențiale pentru construcția interfeței aplicației.

JavaScript este un limbaj de programare orientat obiect bazat pe conceptul prototipurilor, utilizat de programatorii de aplicații Web pentru a construi pagini Web dinamice. Utilitatea acestui limbaj este vizibilă în special la interfețele aplicațiilor web unde pot fi create noi funcționalități printre care: crearea de formulare interactive, validarea informațiilor, răspunsul la diverse evenimente.

JSON este un format de reprezentare a datelor și de interschimbare a acestora între aplicații informatice. Numele de JSON este un acronim pentru JavaScript Object Notation. Este un format text, inteligibil pentru oameni, utilizat pentru reprezentarea obiectelor și a altor structuri de date și este folosit în special pentru a transmite date structurate prin rețea printr-un proces numit serializare. Un avantaj al acestui format îl reprezintă faptul că există implementări ale procesului de serializare și deserializare în aproape orice limbaj de nivel înalt. Astfel poate fi folosit pentru vehicularea datelor între aplicații care folosesc limbaje diferite și are o reprezentare mai simplificată decât principalul concurent: limbajul XML.

Aplicația server este construită peste mediul de dezvoltare Laravel. Laravel este o platformă PHP în continuă dezvoltare care se axează pe un model arhitectural de tip Model-View-Controller (MVC). Laravel are numeroase funcționalități care-l transformă într-un framework extrem de puternic cum ar fi prezența fațadelor(Facades), un sistem ORM( Object-relational mapping) și centralizarea rutelor posibile( fișierul routes.php).

Spre deosebire de celelalte alternative la categoria de platforme PHP(cum ar fi Joomla, WordPress), Laravel este foarte bine optimizat, rapid, ușor de extins și nu este îngreunat de prezența unei interfețe de administrare.

Avantajele structurii MVC devin aparente imediat într-o aplicație cu un cod complex. Fiecare dintre elementele componente are un rol bine definit. Astfel modelul(Model) manipulează operațiunile logice și cele de utilizare ale informației. Componenta „viziune”(View) devine reprezentarea grafică, cu alte cuvinte, exprimarea ultimei forme a datelor. Controlatorul (Controller) trebuie să fie capabil de a manipula fișiere, clase, metode, funcții.

Laravel extinde conceptul de controller permițând construirea de controllere RESTful în jurul unor resurse. Posibilitatea de organizare simplă a codului alături de ușurința de manipula datele și rutele reprezintă motivația alegerii acestei platforme ca bază pentru proiectul dezvoltat.

Sistemul ORM din cadrul platformei Laravel este denumit Eloquent și are rolul de a oferi o implementare simplă de tipul ActiveRecord pentru utilizarea bazei de date. Fiecare tabel din baza de date corespunde unui Model care controlează interacțiunea cu baza de date. Modelele permit interogarea tabelelor și inserarea de date în acestea.

Blade este un motor de șablonare simplu și puternic care nu restricționează folosirea codului PHP în cadrul View-urilor create. Toate șabloanele de tip Blade create sunt compilate în cod PHP iar rezultatul este stocat pe server. Astfel, utilizarea acestor șabloane nu are nici o consecință negativă din punctul de vedere al performanței.

Conceptul de Middleware utilizat în platforma Laravel își propune să ofere un mecanism de filtrare a cererilor HTTP care intră în aplicația Web dezvoltată.

Interfața cu utilizatorul a fost construită pornind de la stilurile și funcționalitatea oferită de Bootstrap, o platformă CSS și JavaScript dezvoltată inițial de Twitter. Ajunsă la versiunea cu numărul 3, platforma permite dezvoltarea de site-uri dinamice care se adaptează la rezoluția dispozitivului. Librăria vine însoțită de un fișier JavaScript și astfel poate oferi o gamă largă de funcționalități, de la simple efecte și meniuri pană la elemente grafice elaborate bazate pe caractere tipografice.

Utilizarea acestei platforme în cadrul proiectului se datorează necesității consistenței interfeței în diversele combinații posibile de dispozitive/navigatoare web și posibilităților aproape nelimitate de extindere a componentelor existente.

JQuery este o librărie rapidă și robustă construită peste limbajul JavaScript. Librăria își propune să simplifice, sa extindă și să adauge funcționalități noi limbajului părinte. Traversarea și modificarea documentelor a devenit astfel o rutină trivială iar manipularea evenimentelor, animațiilor și citirea fișierelor au ajuns să fie standardizate în marea majoritatea navigatoarelor web prin introducerea unui sistem API ușor de învățat și utilizat. Printr-o combinație de versatilitate și capabilitate de extindere, jQuery a schimbat modul în care programatorii abordează dezvoltarea de cod JavaScript. Acest lucru devine evident și în cadrul proiectului, unde, librăria JQuery reprezintă punctul de pornire pentru întregul cod JavaScript creat.

II.2. Tehnologii utilizate la nivelul aplicației client pentru Android

Aplicația client concepută pentru a rula pe terminale Android utilizează un alt subset de limbaje de programare decât aplicația server.

Sistemul de operare Android a fost dezvoltat în jurul unui nucleu Linux și a fost conceput pentru a rula pe dispozitive mobile. Sistemul dezvoltat de firma Google prezintă o interfață bazată pe ideea manipulării directe de către utilizator, folosind gesturi tactile care permit interacțiunea cu elementele de grafică și cu obiectele prezentate pe ecranul dispozitivului. Fiind, în esență, un proiect cu sursă deschisă, sistemul de operare a fost preferat de marii producători de dispozitive mobile deoarece oferă un grad mare de extensibilitate, iar implementarea acestuia nu presupune alte costuri suplimentare.

În cadrul platformei Android, aplicațiile pot fi instalate folosind magazinul online oferit de producător, numit Google Play. Costurile de achiziție a aplicațiilor nu sunt impuse de producătorul platformei, acest aspect fiind la discreția dezvoltatorilor de aplicații. Procesul de publicare a unei aplicații este unul relativ complex care presupune crearea unui cont de dezvoltator în cadrul platformei Web și, totodată, plata unei taxe de înregistrare care are rolul principal de a asigura autenticitatea identității dezvoltatorului.

Dezvoltare aplicației client a fost posibilă prin utilizarea platformei de dezvoltare software Android Studio. Platforma facilitează dezvoltarea de aplicații Android native oferind șabloane și clase de bază în timp ce ecranele specifice aplicațiilor pot fi structurate vizual, utilizând interfața grafică, fiind posibilă definirea de interfețe optimizate doar pentru anumite categorii de dispozitive mobile. Android Studio integrează de asemenea o varietate de unelte de dezvoltare care permit, printre altele:

gestionarea diferitelor librării externe utilizate în cadrul unui proiect

semnarea digitală a aplicațiilor

simularea unor dispozitive standard folosind capabilitățile sistemului gazda

gestionarea dispozitivelor legate prin conexiune USB sau LAN

analiza performantei aplicațiilor

Java este un limbaj de programare complet, orientat-obiect, dezvoltat și comercializat de Sun Microsystems. Prin intermediul limbajului Java, descendent al familiei de limbaje de programare C și C++, programatorii pot crea diverse aplicații și pot controla funcționarea diverselor aparate electronice. Spre deosebire de alte limbaje, Java oferă promisiunea compatibilității inter-platformă.

Utilizarea acestui limbaj de programare pentru dezvoltarea aplicației client se justifică prin faptul că sistemul de operare Android permite dezvoltarea de aplicații native doar în limbajul Java. S-a ales această opțiune în detrimentul altor limbaje sau platforme datorită cerințelor de performanță; aplicația vehiculează în orice moment un număr mare de imagini, conexiuni către server și fire de execuție în paralel.

Un alt limbaj care stă la temelia dezvoltării aplicațiilor pe sistemul de operare Android este XML. XML reprezintă un acronim pentru Extensible Markup Language și este un meta-limbaj de marcare, un model de stocare a datelor nestructurate și semi-structurate. În cadrul dezvoltării aplicației pe Android, acest limbaj a fost utilizat pentru a îndeplini mai multe scopuri, printre care cele mai semnificative sunt:

descrierea interfeței și a elementelor componente

descrierea componentelor lingvistice pentru fiecare limbă utilizată

compunerea animațiilor și proiectarea elementelor customizate

definirea culorilor, dimensiunilor, stilurilor

definirea variabilelor utilizate de sistemele API atașate

II.3. Tehnologii utilizate la nivelul aplicației client pentru iOS

În cadrul procesului de dezvoltare a celor două aplicații mobile, s-a optat pentru o implementare nativă cu scopul de a elimina eventualele diferențe de performanță introduse de librarii terțe. Datorită acestui motiv, aplicația client dezvoltată pentru sistemul de operare iOS utilizează un subset diferit de limbaje de programare.

Sistemul de operare iOS a fost dezvoltat de compania Apple cu scopul de a rula exclusiv pe structurile hardware ale dispozitivelor mobile proprii. Similar sistemului Android, interfața este bazată pe ideea manipulării directe de către utilizator, folosind gesturi tactile care permit interacțiunea cu elementele de grafică și cu obiectele prezentate pe ecranul dispozitivului. Fiind un sistem de operare optimizat doar pentru anumite combinații de componente hardware, rata de adopție a acestuia este strâns legata de popularitatea dispozitivelor pe care rulează.

În cadrul platformei iOS, aplicațiile pot fi instalate folosind magazinul online oferit de producător, numit App Store. Costurile de achiziție a aplicațiilor sunt impuse de dezvoltatori de aplicații, în timp ce producătorul sistemului de operare asigură calitatea minimă a acestora.

Procesul de publicare a unei aplicații este unul relativ complex care presupune crearea unui cont de dezvoltator în cadrul platformei Web și, totodată, plata unei taxe anuale. Un pas în plus care trebuie urmat, spre deosebire de ecosistemul Android, este acela de validare a funcționalități aplicației.

Dezvoltare aplicației client a fost posibilă prin utilizarea platformei de dezvoltare software XCode. Platforma facilitează dezvoltarea de aplicații iOS native oferind șabloane și clase de bază în timp ce ecranele specifice aplicațiilor pot fi structurate vizual folosind mediul StoryBoard, fiind posibilă definirea de interfețe optimizate doar pentru anumite categorii de dispozitive mobile.

O limită a platformei de dezvoltare XCode este dată de cerințele de sistem pentru a putea crea aplicații mobile, astfel, dezvoltarea de aplicații se poate întâmpla doar în cadrul sistemului de operare MacOS. Această abordare are însă și avantaje, deoarece simularea dispozitivelor mobile în cadrul sistemului de operare reprezintă un proces simplificat și mai rapid decât cel al competitorilor.

Cocoa și Cocoa Touch reprezintă principalele interfețe de programare a aplicațiilor native care rulează în cadrul sistemelor de operare iOS și MacOs. Ambele medii de dezvoltare includ nucleul Objective C precum și o serie de librării specifice. Astfel, Cocoa Touch, care include librăriile Foundation și UIKit, este utilizată pentru dezvoltarea aplicațiilor care vor rula pe sistemul de operare iOS.

Limbajul Objective C reprezintă o variație iterativă a limbajului de programare C și oferă capabilități extinse, printre care cele mai importante sunt programarea orientată pe obiecte și prezența unui mediu de rulare dinamic. Objective C derivă sintaxa, tipurile de primitive, și elementele de control a execuției prezente in limbajul de programare C și introduce sintaxa necesară pentru a defini clase si metode.

Limbajul Swift este în prezent promovat în defavoarea limbajului Objective C pentru dezvoltarea de aplicații care vor rulează în cadrul ecosistemului Apple. Acest nou limbaj a fost proiectat pentru a putea rula în paralel cu fragmente de cod scrise în Objective C, și reprezintă de fapt un nivel de abstractizare construit deasupra vechiului limbaj. Având în vedere acest aspect, pentru dezvoltarea aplicației client s-a utilizat totuși limbajul Objective C.

Capitolul III. Implementarea aplicației server

Aplicația server dezvoltată în cadrul acestui proiect are ca scop principal crearea unei platforme de administrare a conținutului care va fi afișat în cadrul aplicațiilor client.

Accesul la această secțiune a aplicației este restricționat utilizatorilor comerciali, aceștia având rolul de a adăuga conținutul care va fi promovat. De asemenea, utilizatorii care au rol de administrator pot accesa, altera și elimina informațiile adăugate de alți utilizatori.

Aplicația este implementată folosind Laravel, o platformă construită peste limbajul PHP care oferă pe lângă multe altele, o arhitectură de tipul MVC (Model-View-Controller), un mecanism pentru interogarea și alterarea bazei de date.

III.1. Structura arborelui de navigare

Din pagina principală a aplicației server se poate ajunge la secțiunea de administrare doar prin autentificare ca utilizator cu privilegii elevate. Ca și un utilizator cu privilegii normale, după înregistrare, următorul pas îl reprezintă descărcarea și autentificarea în cadrul aplicațiilor client.

Structura principală de navigare este descrisă în figura III.1.1.

Figura III.1.1 – Structura principală de navigare

În momentul în care un utilizator cu privilegii elevate este autentificat, se afișează pagina principală dedicată utilizatorilor înregistrați. Pornind de la această pagină un utilizator poate să gestioneze diferitele evenimente, locații și galerii. De asemenea în cadrul meniul principal, un utilizator poate să-și altereze detaliile contului și să se deconecteze. Un utilizator de tipul administrator are acces suplimentar la gestionarea conturilor și a categoriilor.

Schema de navigare pentru un utilizator înregistrat este descrisă în figura III.1.2.

Figura III.1.2 – Structura completă de navigare

Prin rularea comenzi php artisan route:list în consolă se poate vizualiza un tabel conținând întreaga structură a site-ului (figura III.1.3). Acest tabel a fost utilizat pe parcursul procesului de dezvoltare pentru verificarea rutelor posibile și a variabilelor atașate.

Fiecare intrare din tabel oferă informații privitoare la metoda acceptată(GET, POST, HEAD; PATCH, PUT, DELETE), adresa relativă, numele intern al rutei, clasa/metoda apelată și eventualele filtre pentru acces.

Figura III.1.3 – Extract parțial din structura detaliată a arborelui de navigare

III.2. Structura bazei de date

Un mare avantaj al platformei Laravel îl reprezintă faptul că implementează conceptul de fișiere de migrare(migrations) și fișiere de definire a datelor inițiale (seeds).

Fișierele de migrare pot fi definite ca un mecanism de control a sub-versiunilor pentru baza de date. Ele facilitează lucrul în echipă prin faptul că permit modificarea bazei de date putându-se reveni oricând la structura care exista la un moment dat.

Rularea tuturor migrațiilor pentru construirea tabelelor din baza de date s-a realizat executând comanda următoare în consolă: php artisan migrate. Există de asemenea și alte comenzi specifice care au fost rulate pentru controlul structurii bazei de date:

php artisan migrare:rollback – Această comandă anulează alterările produse de ultima operație de migrare

php artisan migrate:reset – Anulează toate modificările aduse bazei de date

php artisan migrate:refresh – Anulează toate modificările aduse bazei de date și rulează din nou fișierele de migrare

La implementarea aplicației server s-au definit mai multe fișierele de migrare, ele fiind prezente în cadrul directorului database/migrations.

Fiecare clasă extinde prin definiție clasa Migration din cadrul nucleului Laravel. În cadrul acestor clase s-au definit cele 2 funcții relevante:

up() – care este responsabilă de modificarea structurii la baza de date

down() care este responsabilă de procesul de eliminare a modificărilor aduse de funcția up()

Pentru a simplifica și organiza codul utilizat la crearea structurii bazei de date, în cadrul procesului de dezvoltare a aplicației server, au fost create fișiere de migrare diferite pentru fiecare set de instrucțiuni care controlează conținutul unei tabele.

Adăugarea unei tabele la baza de date s-a realizat prin apeluri statice ale clasei Schema. În continuare se prezintă modalitatea de definire ale uneia dintre tabelele adăugate în baza de date alături de funcțiile ajutătoare oferite de platforma Laravel:

Schema::create( 'users', function ( Blueprint $table ) {

$table->increments( 'id' );

$table->integer( 'role_id' )->unsigned()->default( 0 );

$table->string( 'name' )->default( '' );

$table->string( 'username' )->default( '' )->unique();

$table->string( 'email' )->unique();

$table->string( 'password', 60 );

$table->string( 'api_token', 32 );

$table->rememberToken();

$table->timestamps();

} );

Rularea acestui cod va genera echivalentul următorului cod MySQL:

CREATE TABLE `users` (

`id` int(10) unsigned NOT NULL,

`role_id` int(10) unsigned NOT NULL DEFAULT '0',

`name` varchar(255) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',

`username` varchar(255) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',

`email` varchar(255) COLLATE utf8_unicode_ci NOT NULL,

`password` varchar(60) COLLATE utf8_unicode_ci NOT NULL,

`remember_token` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL,

`api_token` varchar(32) COLLATE utf8_unicode_ci DEFAULT NULL,

`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',

`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'

);

În exemplul de mai sus s-a adăugat tabelei users o coloană id a cărei valoare se incrementează automat la fiecare inserare. Apelurile succesive la $table->string() au rolul de a adăuga o coloană de tipul varchar cu dimensiunea specificată.

Funcția $table->rememberToken() a fost utilizată cu scopul de a crea un câmp de tipul varchar care este utilizat intern de către Laravel pentru stocarea unui șir unic utilizat pentru identificarea utilizatorului. Prin apelul la $table->timestamps() s-au generat două câmpuri care au denumirea standardizată created_at si updated_at în care se vor reține momentele în timp(sub formă de timestamp) la care s-au produs modificările aduse intrări corespunzătoare.

În urma rulării fișierelor de migrare se obține o bază de date având structura din figura III.2.1.

Figura III.2.1 – Structura bazei de date

Următorul pas îl reprezintă completare bazei de date folosind date pentru testare. Acest lucru a fost realizat folosind procesul de seeding. Laravel oferă un șablon referitor la modul în care se poate derula acest proces. S-au creat clase care extind funcționalitatea clasei Seeder oferită de platformă. În cadrul funcției run s-au adăugat toate intrările care urmau să fi inserate în baza de date.

Pentru a funcționa, această clasă trebuie apelată manual din cadrul fișierului DatabaseSeeder astfel: $this->call('CategoryTypesTableSeeder').

Pentru a putea utiliza baza de date și tabele adăugate prin procesul de migrare, s-au creat modele pentru fiecare obiect diferit utilizat în cadru aplicației. În cadrul modelelor au fost descrise proprietățile care pot fi accesate, asignate și ascunse alături de relațiile față de celelalte modele. Laravel oferă o suită de funcții prin care relațiile dintre modele se pot descrie în mod asemănător cu diagramele ERD ( Entity Relationship Diagram ).

III.3. Structura fișierelor șablon pentru interfața cu utilizatorul. Construcția interfeței.

Structura fișierului HTML care este returnat utilizatorului este definit în cadrul platformei Laravel utilizând șabloane scrise folosind Blade.

În cadrul aplicației server, aceste fișiere șablon au fost utilizate pentru împărțirea logică a secțiunilor care sunt create. Definirea diferitelor secțiuni ale unei pagini, în cadrul aplicației dezvoltate, s-a realizat folosind fișierele din dosarul landing alături de fișierul app.blade.php.

Paginile care sunt afișate doar utilizatorilor înregistrați folosesc un șablon diferit față de restul paginilor iar secțiunile principale ale aplicației sunt separate din punct de vedere logic în dosare diferite.

Adăugarea fișierelor de stil și a programelor JavaScript a fost simplificată prin utilizarea a două fișiere șablon: header.blade.php și footer.blade.php. Aceste secțiuni se încarcă pe fiecare pagină returnată utilizatorului. Totodată, acest motor de șablonare a permis afișarea erorilor și mesajelor în mod organizat prin includerea fișierului notifications.blade.php care definește structura HTML și clasele de stil aplicate acestor mesaje.

Foaia de stil principală în cadrul căreia se definesc particularitățile interfeței cu utilizatorul este main.css. Acest fișier este încărcat în cadrul secțiunii <head> imediat după ce sunt încărcate celelalte foi de stil.

Fișierul app.css este rezultatul compilării fișierelor scrise în limbajul Less care sunt disponibile implicit în cadrul platformei Laravel. Aceste fișiere includ și specificația platformei Bootstrap, așadar nu mai este necesară încărcarea separată a foilor de stil pentru a putea folosi această tehnologie.

Script-urile JavaScript care sunt utilizate pentru dezvoltarea aplicației server sunt încărcate în cadrul secțiuni de subsol a pagini cu scopul de a îmbunătăți performanța aplicației. Excepția de la această regula o reprezintă librăriile HTML5 Shim și Respond.js care trebuie încărcate în antetul paginii pentru a asigura funcționarea interfeței în navigatoarele Web depășite (Internet Explorer 8).

Librăriile externe care sunt utilizate pentru dezvoltare interfeței aplicației sunt JQuery, Bootstrap, Bootstrap DateTimePicker și Dropzone.

JQuery este librăria care stă la baza codului JavaScript scris pentru această aplicație și ca atare este primul script în ordinea încărcării.

Boostrap alături de componentele sale sunt încărcate imediat după jQuery. De menționat faptul că a fost necesară includerea librăriei externe Moment.js pentru buna funcționare a componentei DateTimePicker.

Script-ul Dropzone este utilizat în cadrul aplicației pentru gestionarea încărcărilor de imagini pe server. Acesta prezintă avantajul faptului că folosește AJAX(Asynchronous JavaScript and XML) pentru comunicarea dinamică cu server-ul, evitându-se necesitatea de a redirecționa utilizatorul pe o pagină complementară.

În scopul modificări aspectului standard al formularelor s-a utilizat librăria JCF (JavaScript Custom Forms). Această librărie are o structură modulară a fișierelor, astfel s-au încărcat doar fișierele strict necesare pentru aplicația server.

Ultimul script care este încărcat este main.js unde este centralizat codul JavaScript care folosește librăriile anterior menționate. În cadrul acestui fișier, imediat după ce pagina a fost încărcată, se inițiază stilizarea elementelor formularelor.

Totodată se specifică configurația care va fi utilizată de librăria DropZone. Astfel este scris codul care descrie modul de tratare a încărcării cu succes a fișierelor alături de dimensiunea maximă acceptată pentru imagini.

Pentru construcția unei secvențe alfanumerice unice pentru adresa URL a evenimentelor, locațiilor și galeriilor, s-a recurs la scrierea unei funcții care auto-completează acest șir pornind de la câmpul pentru nume sau titlu. Această auto-completare se petrece în timp real, pe măsură ce utilizatorul tastează titlu unui element. Secvența de cod tratează și cazul șirurilor de caractere care conțin caractere românești prin înlocuirea lor cu echivalentul în limba engleză.

De asemenea a fost necesară scrierea unei secțiuni de cod pentru adăugarea datelor de tip interval orar. Acest cod asigură faptul că data terminării unui eveniment nu are cum să fie înainte datei la care începe evenimentul.

III.4 Pagina principală. Paginile de autentificare și înregistrare.

Pagina principală are rolul de a o feri utilizatorilor o modalitate prin care să ajungă la pagina de autentificare și la cea de creare a conturilor. Astfel în cadrul paginii sunt prezente cele două legături esențiale(autentificare și înregistrare) alături legături directe spre fișierele de instalare ale aplicațiilor client pe terminalele Android și iOS ( figura III.4.1 ).

În cadrul fișierului routes.php este specificată funcția care va fi apelată pentru identificarea View-ului care va fi afișat utilizatorului astfel:

Route::get( '/', 'WelcomeController@index' );

Funcționalitatea de creare a conturilor alături de cea de autentificare sunt oferite în mod implicit de platforma Laravel. În cadrul aplicației, această funcționalitate a fost extinsă prin includerea diferitelor roluri pentru utilizatori. Astfel, un utilizator înregistrat poate fi de tipul: administrator, utilizator comercial sau utilizator normal.

Rutele accesibile vizitatorilor sunt definite în fișierul routes.php:

Route::get( 'register', 'Auth\AuthController@getRegister' );

Route::post( 'register', 'Auth\AuthController@postRegister' );

Route::get( 'login', 'Auth\AuthController@getLogin' );

Route::post( 'login', 'Auth\AuthController@postLogin' );

Controller-ul utilizat este AuthController. În cadrul acestui controller sunt definite funcțiile care adaugă și autentifică utilizatorii.

La înregistrarea unui utilizator, datele provenite din formular sunt validate înaintea introducerii lor în baza de date. Astfel numele de utilizator și adresa de e-mail trebuie este verificată pentru a asigura unicitatea în cadrul tabelei din baza de date. Funcția ajutătoare bcrypt oferită de Laravel este folosită pentru criptarea parolelor.

Modelul User este folosit de AuthController pentru interacțiunea cu baza de date. În cadrul modelului sunt definite relațiile față de celelalte modele. Astfel un utilizator poate să fie autorul mai multor evenimente, galerii, locații, imagini și categorii însă poate avea doar un singur rol.

Ecranele de autentificare și înregistrare sunt prezentate în figurile IV.5.2, respectiv IV.5.3.

Figura III.4.2 – Interfața paginii de autentificare

Figura III.4.3 – Interfața paginii de înregistrare

III.5 Pagina principală pentru utilizatori autentificați

Prin autentificare, un utilizator comercial este redirecționat către pagina principală pentru utilizatori comerciali. Rolul acestei pagini este de a oferi utilizatorilor o modalitate rapidă de a ajunge la toate punctele de interes din cadrul aplicației server.

Antetul paginii este marcat de către meniul principal, de aici un utilizator poate vizualiza și altera propriile locații, evenimente și galerii. Tot aici se oferă utilizatorului opțiunea de a-și edita propriu cont sau de ieși din cont.

Utilizatorii care au rol de administrator pot de asemenea să administreze utilizatorii și categoriile principale în care se pot adăuga date. Totodată, administratorii pot altera locațiile, evenimentele și galeriile oricărui utilizator. Interfața paginii este prezentată în figura III.5.1.

Conținutul paginii este secționat în trei coloane principale unde s-au listat numărul de evenimente, galerii și locații adăugate. În interiorul fiecărei coloane, s-a adăugat un buton care redirecționează spre pagina unde se listează numărul de intrări pentru fiecare categorie.

Controller-ul utilizat este HomeController. Pentru prezentarea datelor de pe pagina principală, funcția index folosește modelele tabelelor de locații, evenimente și galerii pentru a afla numărul de intrări, prezente în baza de date, pentru fiecare utilizator.

De exemplu preluarea numărului de evenimente pentru un utilizator s-a realizat folosind următoarea secveță de cod:

Auth::user()->galleries()->count();

Această secțiune de cod utilizează avantajul relațiilor dintre modele pentru a obține informații referitoare la numărul evenimentelor pornind de la utilizatorul curent.

III.6 Paginile de gestionare a categoriilor

Secțiunea de gestionare a categoriilor, în cadrul aplicației Web. este accesibilă doar utilizatorilor care au rol de administrator. Această limitare a fost instituită ca și o metodă simplă și rapidă de a guverna tipul de conținut care se poate adăuga de către utilizatorii comerciali.

Pagina pe care sunt listate categoriile este accesibilă prin intermediul meniului din antetul paginii principale a utilizatorilor autentificați. Pentru afișarea organizată a categoriilor s-a utilizat mecanismul de paginație oferit de către Laravel. Structura interfeței este prezentată în figura III.6.1.

Adăugarea de elemente noi e facilitată de prezența unui buton în partea stângă sus care redirecționează utilizatorul spre o pagină unde se pot introduce datele.

Fiecare intrare din tabel prezintă o culoare de fundal alternantă alături de un set de butoane în partea stângă prin care se pot elimina sau edita intrările. Înainte ca un utilizator să șteargă o categorie, se afișează un mesaj de confirmare, aceasta fiind o metodă de protecție la apăsările accidentale ale butonului.

Controller-ul utilizat este de tipul RESTful, iar înregistrarea acestuia se face folosind: Route::resource('categories', 'CategoriesController');

Controller-ul CategoriesController folosește modelul Category pentru manipularea datelor referitoare la o categorie. Controller-ul ImagesController are aici un rol invizibil utilizatorului deoarece este apelat din cadrul CategoriesController pentru stocarea imaginilor.

Validarea datelor s-a realizat înaintea salvări datelor referitoare la o categorie în baza de date. Procedura de validare folosite asigură corectitudinea datelor prin urmarea următoarelor reguli:

Numele unei categorii trebuie să fie specificat iar lungimea acestuia trebuie să fie de maxim 255 de caractere

Tipul unei categorii trebuie să existe anterior în baza de date

Imaginea trebuie să aibă o dimensiune a fișierului mai mică de 10 mega-octeți iar formatul acceptat poate fi doar: jpeg, bmp, png

În momentul editării unei categorii, dacă este necesar, imaginea anterioară este ștearsă de pe server pentru a face economie de spațiu.

III.7 Paginile de gestionare a evenimentelor. Paginile de gestionare a locațiilor

Secțiunea de gestionare a evenimentelor este disponibilă tuturor utilizatorilor cu un cont de tipul comercial. Articolele care sunt prezentate pe pagina de listare a evenimentelor diferă de la un tip de utilizator la altul. Astfel administratorii pot vedea și altera toate evenimentele adăugate în timp ce utilizatorii comerciali pot să vizualizeze doar evenimentele proprii.

Adăugarea de noi evenimente se poate face folosind butonul din partea stânga sus a interfeței; utilizatorul este redirecționat spre o pagină cu un formular în care trebuie introduse toate datele necesare. Interfața pagini de adăugare a unui eveniment nou e surprinsă în figurile III.7.1.

În cadrul paginilor de editare și adăugare, locațiile sunt preluate automat de pe server, iar utilizatorul poate să utilizeze doar locațiile care le-a adăugat anterior. Câmpurile în care se completează intervalele de timp sunt dinamice; s-a utilizat extensia Bootstrap DateTimePicker pentru afișarea unei interfețe specializate.

La eliminarea unui eveniment se afișează un mesaj de confirmare ca și o măsură de siguranță împotriva apăsărilor accidentale ale butoanelor din interfață.

Spre deosebire de tipurile de date prezentate anterior(categorii și utilizatori), evenimente conțin în cadrul bazei de date un câmp numit slug al cărui rol este acela de asigura o adresă URL alfanumerică unică pentru fiecare eveniment. Astfel, în cadrul fișierului pentru definirea rutelor, a fost adăugată o secțiune de cod care recunoaște un obiect de tipul modelului Event după câmpul slug:

Route::model('events', 'Event');

Route::bind('events', function($value, $route) {

return App\Event::whereSlug($value)->first();

});

Route::resource('events', 'EventsController');

Validarea datelor se realizează înaintea salvări datelor referitoare la un eveniment. Procesul de validare folosite asigură corectitudinea datelor prin urmarea următoarelor reguli:

Numele unei categorii trebuie să fie specificat iar lungimea acestuia trebuie să fie de maxim 255 de caractere

Câmpul slug trebuie să fie alfanumeric ( se acceptă și caracterele underscore, dash) și în același timp unic în tabela din baza de date

Tipul unei categorii trebuie să existe anterior în baza de date

Descrierea unui eveniment poate fi de maxim 1000 de caractere

Imaginea trebuie să aibă o dimensiune a fișierului mai mică de 10 mega-octeți iar formatul acceptat poate fi doar: jpeg, bmp, png

Datele de început și sfârșit ale unui eveniment trebuie să fie în ordine cronologică și trebuie să fie specificate în formatul acceptat de PHP „Y-m-d H:i:s”

Paginile dedicate gestionării locațiilor sunt accesibile utilizatorilor comerciali tot prin intermediul meniului principal. Similar secțiuni de gestionare a evenimentelor, se realizează o filtrare a locațiilor adăugate de către utilizatori. Astfel administratorii pot modifica locațiile adăugate de orice utilizator însă aceștia din urmă pot vizualiza doar propriile intrări.

Interfața urmează același model, diferența fiind reprezentată de prezența unei legături spre galeria atașată unei locații pe pagina de gestionare a acestora.

Similar cu modul de înregistrare a rutelor spre evenimente, în cadrul fișierului pentru definirea rutelor, a fost adăugată o secțiune de cod care recunoaște un obiect de tipul modelului Location folosind câmpul slug:

Route::model('locations', 'Location');

Route::bind('locations', function($value, $route) {

return App\Location::whereSlug($value)->first();

});

Route::resource('locations', 'LocationsController');

În cadrul paginilor de editare și adăugare, galeriile sunt preluate automat de pe server, iar utilizatorul poate să utilizeze, pentru locații, doar galeriile care le-a adăugat anterior. Interfața paginii de editare a unei locații este detaliată în figura III.7.2.

Validarea datelor se petrece înaintea adăugării unei locații iar regulile respectate sunt urătoarele:

Numele unei categorii trebuie să fie specificat iar lungimea acestuia trebuie să fie de maxim 255 de caractere

Câmpul slug trebuie să fie alfanumeric ( se acceptă și caracterele underscore, dash) și în același timp unic în tabela din baza de date

Tipul unei categorii trebuie să existe anterior în baza de date

Descrierea unui eveniment poate fi de maxim 1000 de caractere

Adresa unei locații trebuie să aibă maxim 150 de caractere iar coordonatele referitoare la latitudine și longitudine trebuie să fie de tip numeric

Imaginea trebuie să aibă o dimensiune a fișierului mai mică de 10 mega-octeți iar formatul acceptat poate fi doar: jpeg, bmp, png

Adresa web trebuie să fie o pagină web activă

Numărul de telefon trebuie să aibă exact 10 cifre

III.8 Paginile de gestionare a galeriilor

Interfața paginilor de gestionare a galeriilor urmează modelul prezentat anterior pentru locații și evenimente. Distincția provine din faptul că a fost necesară dezvoltarea unei modalități de gestionare a imaginilor din cadrul unei galerii.

Astfel, la nivel de interfață, pagina principală în cadrul căreia sunt listate galeriile prezintă în cadrul tabelului un set diferit de butoane față de celelalte pagini. S-a adăugat un buton care redirecționează spre o pagină prin care se pot gestiona imaginile alături de butonul de editare și de eliminare ale unei galerii.

Pagina de gestionare a galeriilor prezintă în antet o un chenar prin intermediul căruia se pot adăuga imaginile. Imaginile sunt încărcate prin AJAX, iar după primirea răspunsului de la server, ele sunt adăugate într-un tabel poziționat imediat sub chenar. Fiecare imagine adăugată în galerie poate fi eliminată prin intermediul unui buton poziționat imediat sub imagine. Interfața de gestionare a imaginilor este descrisă în figura III.8.1.

Mecanismul de adăugare a imaginilor în mod dinamic a fost realizat folosind script-ul DropZone. Acest script apelează server-ul pentru fiecare imagine adăugată și primește ca răspuns noua denumire a fișierului. Imaginile adăugate pe server sunt validate, redimensionate și redenumite iar de datele de identificare sunt adăugate în baza de date.

Înregistrarea rutelor pentru galerii urmează modelul folosit pentru evenimente și locații, cu câteva excepții. Astfel, pe lângă rutele oferite de controller-ul RESTful GalleriesController, s-au adăugat două rute complementare pentru salvarea și eliminarea imaginilor. Aceste alterări s-au realizat folosind următoarea secțiune de cod:

Route::model('galleries', 'Gallery');

Route::bind('galleries', function($value, $route) {

return App\Gallery::whereSlug($value)->first();

});

Route::post('galleries/{galleries}/storeimage', ['as' => 'galleries.storeimage', 'uses' => 'GalleriesController@storeImage']);

Route::post('galleries/{galleries}/destroyimage', ['as' => 'galleries.destroyimage', 'uses' => 'GalleriesController@destroyImage']);

Route::resource('galleries', 'GalleriesController');

Controller-ul GalleriesController se folosește de modelul Gallery pentru interacțiunea cu baza de date.

Pentru gestionarea imaginilor s-a creat un controller ImagesController care este folosit doar intern de celelalte controllere. Pentru manipularea efectivă a fișierelor acesta utilizează scriptul image_lib din cadrul platformei Web CodeIgniter.

Regulile de validare pentru adăugarea unei imagini sunt următoarele:

Numele unei galerii trebuie să fie specificat iar lungimea acestuia trebuie să fie de maxim 255 de caractere

Câmpul slug trebuie să fie alfanumeric ( se acceptă și caracterele underscore, dash) și în același timp unic în tabela din baza de date

Categorii trebuie să existe anterior în baza de date

Imaginea trebuie să aibă o dimensiune a fișierului mai mică de 10 mega-octeți iar formatul acceptat poate fi doar: jpeg, bmp, png

Data la care este adăugată o galerie trebuie să fie specificată în formatul acceptat de PHP „Y-m-d H:i:s”

Capitolul IV. Sistemul REST API

Legătura din platforma dezvoltată și aplicațiile mobile s-a realizat prin crearea unui sistem API.

Fiecare aplicație mobilă realizează apeluri asincrone spre sistemul API care utilizează arhitectura existentă a platformei pentru a accesa baza de date și returna datele cerute.

Înregistrarea traseului înspre sistemul API s-a realizat folosind următoarea secvență de cod:

Route::get('api', 'APIController@handleRequest');

După cum se poate observa, controller-ul APIController este folosit pentru prelucrarea și returnarea datelor. Acesta utilizează toate modelele descrise în aplicație împreună cu relațiile dintre ele și generează un răspuns în limbajul JSON.

Limbajul JSON a fost ales aici datorită ușurinței de a genera un astfel de răspuns din partea platformei Laravel. De asemenea, interpretarea acestui limbaj pe partea de aplicație client are avantajul faptului că se poate realiza nativ, folosind obiectele JSONArray și JSONObject din Java.

Răspunsul JSON returnat de server are următoarea structură:

[ 'error' => true/false, 'message' => String, 'data' => String ];

În contextul răspunsului JSON, câmpul error va fi true doar în cazul în care s-a întâmpinat o eroare la validarea datelor sau la construcția obiectelor returnate. Câmpul message va conține mesajul de eroare dacă este cazul, atfel va fi null. Câmpul data conține informațiile utile care vor fi returnate aplicației client; pot fi returnate obiecte cu structuri complicate codate sub formă de șir de caractere.

Structura cererilor înaintate sistemului API poate să varieze de la un caz la altul, însă permanent trebuie definite cele 3 variabile fundamentale în absența cărora se va genera o eroare: client, token și task.

Variabila client se referă în contextul de față la tipul aplicației și poate fi un șir de caractere alfanumeric de o lungime exactă (32 de caractere). Sistemul API ignoră orice cerere care nu este semnată de un șir cunoscut.

Astfel în constructorul clasei ApiController s-a definit un șir de caractere care să corespundă clientului de pe Android. Acest șir de caractere este inclus de asemenea în codul sursă al fiecărei aplicații mobile dezvoltate și reprezintă o măsură de precauție suplimentară pentru validarea autenticității cerilor.

Următoarea variabilă importantă care trebuie definită în cadrul cererii este token-ul. Acest token este un șir alfanumeric cu o lungime variabilă (32-48 de caractere) prin care se identifică utilizatorul din contul căruia se inițiază cererea. Pentru a obține acest token, aplicația client trebuie întâi să autentifice utilizatorul.

Variabila task desemnează tipul de informație care se cere de la server. În acest sens sunt definite în cadrul constructorului controller-ului setul de task-uri acceptate. De menționat este faptul că s-a urmărit aici o abordare de tipul validare white-list.

Așa cum se poate observa în cadrul secțiunii de cod pentru înregistrarea rutei spre sistemul API, din cadrul controller-ului este apelată funcția handleRequest care realizează validarea datelor și desemnează care funcții se vor ocupa de generarea răspunsului. Funcția handleRequest verifică dacă următoarele condiții sunt împlinite:

cererea trebuie să aibă cele trei variabile esențiale, iar acestea trebuie să îndeplinească normele de lungime / tip de date

șirul de caractere care identifică clientul trebuie să fie valid

task-ul specificat trebuie sa fie în lista task-urilor acceptate

parametrii pentru fiecare task trebuie să îndeplinească normele de lungime/ tip de date

Pentru determinarea regulilor de validare, care pot să difere de la un task la altul, s-a creat funcția internă getTaskValidationRules care generează această listă de reguli.

Limitarea numărului de articole returnate se face folosind parametrii limit și limit_start care pot fi acceptați de marea majoritate a funcțiilor. Ca și o măsură de protecție împotriva cererilor masive de date, s-a impus o limită maximă de 999 de elemente returnate.

Pentru obținerea adreselor URL ale imaginilor de pe server, s-a creat o funcție separată care utilizează controller-ul ImagesController și generează o listă de adrese care va codată în JSON.

După o primă conectare la sistemul API, nu se poate satisface nici o cerere fără a obține codul de identificare unic al utilizatorului de la server. Codul de identificare unic este stocat în baza de date, în cadrul tabelei users.

La fiecare cerere de autentificare, sistemul API va regenera codul de identificare, ca și o măsură de precauție pentru a asigura faptul că un utilizator este autentificat doar dintr-un singur loc, la un moment dat.

Dacă se încearcă utilizarea frauduloasă a sistemului API folosind coduri de identificare diferite, doar cererile care folosesc ultimul cod generat de server vor fi acceptate. Astfel, pentru a utiliza sistemul API, aplicația trebuie întâi să urmeze procedura de autentificare.

Datele utilizatorului nu sunt memorate într-o sesiune, pentru sistemul API, așa că nu a fost nevoie să se includă o procedură pentru ieșire din cont (logout).

În cadrul sistemului API, răspunsul pentru fiecare task este construit în funcții dedicate. Secvența următoare de cod ilustrează modul de construcție a răspunsului pentru o cerere de returnare a unei locații:

private function handleGetLocationRequest( $request, $task ) {

$location = Location::find( Input::get( 'location_id' ) );

$location->image = $this->getImagePaths( $location->image_id );

$location->galleryCount = $location->galleries()->count();

$location->eventCount = $location->events()->count();

$this->returnData['data'] = $location;

}

Aici, tabloul returndata este utilizat pentru completarea datelor care vor fi returnate în format JSON clientului.

Prin structura expusă în paragrafele anterioare, sistemul API reușește să asigure comunicația, în mod securizat, dintre aplicația server și terminalele care rulează aplicațiile client. Datorită utilizării platformei Laravel, această comunicație se desfășoară foarte rapid; prelucrarea datelor care vor fi returnate nu consumă un număr mare resurse.

Capitolul V. Implementarea aplicațiilor client

Aplicațiile client dezvoltate în cadrul acestui proiect au ca scop principal expunerea unei interfețe prin care utilizatorii să poată vizualiza evenimentele promovate în cadrul aplicației server. Accesul la aplicații este restricționat utilizatorilor înregistrați în cadrul platformei web. Nu se face o distincție între utilizatorii autentificați întrucât, prin intermediul aplicației client, nu se pot altera datele de pe server.

Folosind sistemul API, fiecare aplicație obține datele de la server în mod securizat. Funcționalitatea aplicației nu este limitată la afișarea acestor date. Prin integrarea cu unul din serviciile oferite gratuit de compania Google, și anume Google Maps API, utilizatorul poate utilizata interfața pentru a afla cea mai scurtă ruta spre o locație, pornind de la poziția curentă. De asemenea, prin utilizarea serviciului Google Analytics se pot studia datele referitoare numărul de utilizatori care utilizează aplicația precum și preferințele acestora.

La prima deschidere a aplicației, utilizatorul este întâmpinat de ecranul de autentificare. Prin validarea datelor inserate și primirea răspunsului de la sistemul API, utilizatorul este redirecționat spre ecranul meniului principal.

Structura principală de navigare în cadrul aplicațiilor mobile este descrisă în figura V.1. Se menționează faptul că în această figură nu sunt incluse relațiile dintre diferitele ramuri ale arborelui de navigare. Astfel de la un eveniment se poate ajunge la o locație, iar din cadrul unei locații se pot lista galerii.

V.1 Implementarea aplicației client Android

Aplicația a fost dezvoltată folosind limbajul Java și editorul oferit de către creatorul sistemului de operare Android, Android Studio. O astfel de dezvoltare care implică utilizarea limbajului nativ oferă un grad sporit de performanță, rapiditate și acces la resurse față de alte soluții software existente (cum ar fi PhoneGap).

Structurarea logică a codului executat pentru fiecare ecran s-a realizat folosind Activități(Activity) și Fragmente(Fragment). Activități noile noi au fost create pentru separa funcționalitatea fiecărei secțiuni și pentru a opri propagarea eventualelor erori.

Pentru interacțiunea cu baza de date s-au creat un set de clase ajutătoare care realizează conectarea la server, prelucrarea datelor și actualizarea interfeței. Secțiunile de conectare la server și prelucrare datelor au fost incluse în clase care extind funcționalitatea oferită de DataCollection, o clasă pentru stocarea datelor care a fost creată special pentru gestionarea asincronă a datelor. Aceste clase au fost structurate în sub-dosare specifice în cadrul dosarului data.

Clasele Model au fost utilizate pentru a reține datele specifice fiecărei secțiuni. Această organizare a fost necesară deoarece structura răspunsului de la server poate să difere în funcție de complexitatea datelor cerute. Clasele din cadrul dosarului adapter au rolul de a mapa datele din interiorul modelelor cu diferitele porțiuni ale interfeței. Tot în cadrul acestor fișiere au loc verificările care asigură reutilizarea corectă a porțiunilor interfeței pentru a spori performanța.

Aplicația utilizează un sub-proiect numit Library în care sunt specificate elementele abstracte utilizate în cadrul aplicației. Aici sunt incluse clasele ajutătoare pentru gestiunea asincronă a datelor, interfațarea cu serviciile Google și elementele grafice customizate.

La pornirea aplicației se pornește o instanță a clasei App care are rolul de inițializa setările, prin apeluri la clasa statică AppSettings. Tot din această clasă are loc inițializarea setărilor pentru utilizarea Google Analytics.

Odată ce elementele necesare au fost inițializate, din clasa App încep să fie afișate ecranele corespunzătoare.

V.1.1 Ecranul de autentificare

La prima deschidere a aplicației, utilizatorul este întâmpinat de ecranul de autentificare. În cadrul acestui ecran, au fost adăugate două butoane principale prin care utilizatorul se poate autentifica sau poate să-și creeze un cont. Ambele butoane se folosesc de datele care au fost completate în cadrul câmpului „server”. Interfața ecranului de autentificare este prezentat în cadrul figurii V.1.1.1.

Odată cu apăsarea butonului pentru autentificare, are loc testarea conexiuni către server și verificarea datelor introduse de utilizator.

După confirmarea datelor utilizatorului, server-ul trimite un răspuns înapoi aplicației client prin care se specifică câmpul token care va fi utilizat pentru marcarea viitoarele cereri înaintate server-ului.

Câmpurile care trebuie completate de utilizator sunt cele corespunzătoare numelui de utilizator, parolei și adresei server-ului. De menționat este faptul că acel câmp care corespunde adresei server-ului a fost adăugat în cadrul aplicației doar cu scopul de a demonstra funcționalitate acesteia folosind o instanță a platformei care este rulată local.

Pentru implementarea acestui ecran s-a creata activitatea LoginActivity care folosește o instanță a clasei LoginDataCollection pentru manipularea datelor. Clasa LoginDataCollection lansează un nou fir de execuție pentru a conectarea la server și prelucrarea datelor. La finalizarea acestui fir de execuție este apelată funcția onDataAvailable din cadrul LoginActivity care are rolul de afișa ecranul principal.

V.1.2 Ecranul principal

Ecranul meniul principal este disponibil utilizatorului imediat după procesul de autentificare. Acest ecran are rolul de a facilita accesul direct sau indirect al utilizatorului la toate funcționalitățile oferite de aplicație. Astfel are loc o diferențiere a secțiunilor aplicației. Interfața meniului principal este surprinsă în cadrul figurii V.1.2.1.

Din meniul principal utilizatorul poate vizualiza direct categoriile corespunzătoare locațiilor, galeriilor și evenimentelor. Tot prin meniul principal utilizatorul poate fi redirecționat către adresa site-ului, poate efectua o căutare după cuvinte sau poate vizualiza un calendar al evenimentelor.

Activitatea MainActivity utilizează fragmentul MainFragment în cadrul căruia sunt definite elementele care vor fi adăugate în meniu.

Imaginile utilizate sunt încărcate din spațiul de stocare a dispozitivului întrucât structura meniul nu poate fi alterată de către utilizatori.

La apăsarea fiecărei pictograme, fragmentul principal din MainActivity este înlocuit de către un nou fragment corespunzător. Excepția de la această regulă o reprezintă butonul denumit „Site Web” pentru care este lansată o nouă instanță a navigatorului implicit de pe dispozitiv folosind următoarea secvență de cod:

startActivity(newIntent(Intent.ACTION_VIEW, Uri.parse(AppSettings.API_DOMAIN)));

Adaptorul MenuGridViewAdapter este folosit pentru realizarea legăturii dintre datele reținute în MenuGridItemModel și elementele interfeței așa cum sunt ele specificate în cadrul fișierelor XML. Structura interfeței este schițată folosind fișierul fragment_list_standard_compact.xml. Acest fișier folosește un GridView pentru spațierea uniformă a elementelor. Structura detaliată a elementelor a fost inclusă într-un fișier XML separat numit: item_model_menu_list.xml

V.1.3 Ecranele de vizualizare a locațiilor

Secțiunea aplicației corespunzătoare locațiilor este accesibilă folosind meniul principal. Prin selectarea unei categorii, utilizatorul poate vizualiza o listă de locații disponibile alături de imaginile de prezentare ale acestora.

Activitatea LocationListActivity este utilizată pentru listarea locațiilor. Această activitate primește ca parametri din partea MainActivity numele categoriei și câmpul id al acesteia. Parametrii sunt transmiși în continuare la LocationListFragment care folosește o instanță a clasei ajutătoare ETGridImageViewer prin care elemente sunt poziționate pe ecran în mod ordonat. Fragmentul are de asemenea rolul de a transmite mai departe parametrii necesari pentru activități ca răspuns la evenimentele de apăsare a ecranului.

Structura acestui ecran este descrisă folosind figura V.1.3.1.

La selectarea unei locații din cadrul listei de locații, se lansează activitatea LocationDetailActivity care transmite în continuare parametrul primit (câmpul id al locației) la fragmentul LocationDetailFragment. Definirea funcționalității paginii pentru locații este definită în LocationDetailFragment. Interfața corespunzătoare ecranului de prezentare al unei locații este prezentat în figura V.1.3.2.

În cadrul acestui ecran, un utilizator poate vizualiza o scurtă descriere adăugată de autorul locației. De asemenea, tot prin această interfață un utilizator poate ajunge în cadrul unor ecrane unde sunt listate galeriile și evenimentele pentru locația respectivă.

Există unele elemente ale interfeței care prezintă funcționalități avansate. Astfel prin apăsarea textului care corespunde unei adrese, se lansează o instanță a LocationMapActivity care utilizează Google Maps API pentru afișarea poziției locației pe hartă. Totodată, butonul numit „Localizare” lansează o interfață prin care utilizatorul poate afla ruta optimă spre coordonatele locației. Această rută se actualizează automat și ca atare poate fi folosită în locul soluțiilor software GPS dedicate.

Numărul de telefon al unei locații reprezintă de asemenea un element interactiv care lansează aplicația implicită de apelare a dispozitivului; are loc o autocompletare a numărului de telefon astfel încât utilizatorul nu trebuie să copieze acest număr din cadrul aplicației. Această funcționalitate a fost implementată folosind următoarea secvență de cod.

Intent callIntent = new Intent(Intent.ACTION_DIAL);

callIntent.setData(Uri.parse("tel:" + PhoneNumberUtils.formatNumber( dataCollection.getData(locationID).get(0).getPhone())));

startActivity(callIntent);

V.1.4 Ecranele de vizualizare a evenimentelor

În cadrul secțiunii de vizualizare a evenimentelor, ecranul corespunzător listei de evenimente și categorii este în mare parte similar cu ecranul de listare a locațiilor. Diferența e reprezentată de prezența unor informații adiționale pentru fiecare eveniment. Astfel, în cadrul procesului de listare a evenimentelor s-au afișat în plus data de începere și numele locației.

La selectarea unui eveniment din listă, activitatea EventDetailActivity primește ca parametrii câmpul id al evenimentului un tablou conținând câmpurile id ale evenimentelor din aceeași categorie. Interfața construită folosind această activitate este ilustrată în figura V.1.4.1.

Datele referitoare la evenimentele din aceeași categorie sunt necesare deoarece, la ecranul de vizualizare a unui eveniment, există opțiunea de a naviga la următoarele evenimente. Acest stil de navigare folosind glisarea cu degetul la marginile ecranului, pe plan orizontal, s-a realizat folosind clasa ETPagerImageViewer și elementul ETViewPager.

Informațiile vizibile pentru un eveniment sunt:

numele evenimentului

numele locației

data de începere

imaginea de prezentare

descrierea dinamică (HTML)

Numele locației este subliniat cu scopul de a evidenția faptul că este un element interactiv; textul redirecționează utilizatorul spre ecranul unde sunt prezentate datele locației.

V.1.5 Ecranele de vizualizare a galeriilor

Spre deosebire de interfețele prezentate anterior, secțiunea galeriilor prezintă o interfață de vizualizare a imaginilor din cadrul unei galerii. Astfel din cadrul ecranului de listare a galeriilor, prin selectarea unei galerii(figura V.1.5.1), se afișează fragmentul de listare a imaginilor(figura V.1.5.2).

La selectarea unei imagini, din cadrul GalleryFragment este creată o instanță a activității GalleryDetailActivity care primește ca parametrii titlul și câmpul id al galeriei alături de numărul de ordine al imaginii care urmează a fi afișată. Din această activitate se setează parametrii pentru cache și se creează o instanță a ETPagerImageViewer în momentul în care se semnalează faptul că datele au fost încărcate.

Activitatea oferă funcționalitatea de ascundere și afișare a interfeței alături de opțiunea de a salva imagini.

Clasa ETPagerImageViewer are rolul de a oferi o interfață optimizată pentru imagini, cu navigare succesivă între pagini, folosind tehnica de glisare a degetului pornind de la marginea ecranului(pe plan orizontal). Din cadrul acestei clase se creează și se memorează instanțe ale GalleryFragment.

Crearea unei instanțe a ETPagerImageViewer s-a realizat folosind următoarea secvență de cod:

imageViewer = new ETPagerImageViewer(this,imageFetcher,galleryPager,galleryAdapter,null);

imageViewer.setOffscreenPageLimit(AppSettings.CACHE_MAX_PAGES);

În cazul de față, variabila imagefetcher este o instanță a ImageFetcherHTTP iar constanta CACHE_MAX_PAGES reprezintă numărul maxim de elemente care vor fi reținute de către elementul ViewPager în memorie.

V.1.6 Ecranul de căutare. Ecranul secțiunii calendar

Secțiunea de căutare este accesibilă din meniul principal al aplicației și diferă de interfețele utilizate în celelalte secțiuni. Interfața este alcătuită de un element EditText în care utilizatorul poate să introducă expresia căutată și un meniu prin care se pot alege filtrele aplicate căutării. Structura interfeței este descrisă în figura VI.6.1.

Clasa SearchFragment este utilizată direct de către MainActivity, fără a fi nevoie de a trece prin o altă activitate. Această abordare a fost aleasă datorită faptului că această interfață nu prezintă, inițial, elemente care se încarcă dinamic.

Funcția din cadrul fragmentului care realizează căutarea este denumită search. Înaintea lansării unei operații de căutare se verifică lungimea expresiei căutate iar daca aceasta nu este de minim trei caractere, un mesaj de eroare e afișat utilizatorului.

Elementele care alcătuiesc interfața unei intrări ale listei afișate utilizatorului sunt specificate în fișierul item_model_search_list.xml, iar maparea datelor cu elementele interfeței se realizează folosind clasa SearchListViewAdapter.

Secțiunea dedicată calendarului de asemenea nu respectă tiparul expus anterior, la secțiunile de locații, evenimente și galerii. Interfața este alcătuită din o serie de butoane interactive prin care utilizatorul poate vizualiza evenimentele sau galeriile pentru o zi specifică.

Ziua curentă este marcată special în cadrul calendarului iar utilizatorul poate naviga secvențial între lunile anului. La selectarea unei zile, are loc afișarea unei ferestre de tip dialog, unde sunt listate evenimente sau galerii.

Interfața calendarului este construită utilizând clasa CalendarFragment care este apelată direct din MainActivity. Nu s-a optat pentru dezvoltarea unei activități suplimentare datorită faptului că această interfață constă din un singur ecran. Interfața secțiunii calendar este expusă în figura V.1.6.2.

V.2. Implementarea aplicației client iOS

Aplicația a fost dezvoltată folosind limbajul Objective C în cadrul platformei de dezvoltare XCode oferită de producătorul sistemului de operare. Într-un mod similar implementării aplicației pentru sistemul Android, o astfel de dezvoltare care implică utilizarea limbajului nativ oferă un grad sporit de performanță, rapiditate și acces la resurse față de alte soluții software existente.

Structurarea logică a codului executat pentru fiecare ecran s-a realizat folosind clase de tip ViewController. Utilizând mediul grafic Storyboard, s-a realizat conexiunea dintre elementele de interfață ale aplicației și clasele dedicate bazate pe limbajul Objective C.

Pentru interacțiunea cu baza de date s-au creat un set de clase care realizează conectarea la server, prelucrarea datelor și actualizarea interfeței. Astfel clasele Model au fost utilizate pentru a reține datele specifice fiecărei secțiuni. Această organizare a fost necesară deoarece structura răspunsului de la server poate să difere în funcție de complexitatea datelor cerute.

Clasele din cadrul dosarului views au rolul de a mapa datele din interiorul modelelor cu diferitele porțiuni ale interfeței. Tot în cadrul acestor fișiere au loc verificările care asigură reutilizarea corectă a porțiunilor interfeței pentru a spori performanța.

Aplicația utilizează și un set de clase ajutătoare care au rolul de a centraliza si abstractiza porțiunile de cod utilizate frecvent în cadrul aplicației. Aici sunt incluse și secvențele de cod pentru gestiunea asincronă a datelor, interfațarea cu serviciile Google și prelucrare sau conversia datelor.

La pornirea aplicației se pornește o instanță a clasei POAppDelegate care are rolul de inițializa setările și de a seta stilurile utilizate de sistem pe parcursul afișării aplicației. Structura fragmentată a aplicației precum și relațiile dintre diferitele stadii ale interfeței pot fi observate în figura V.2.1. Maparea elementelor interfeței la variabile ce pot fi utilizate în cadrul codului sursă nu reprezintă un proces intuitiv. Astfel, fiecare element de interfață trebui asignat manual, utilizând vederea partajata oferită de editor (figura V.2.2). Asignarea elementelor se realizează la nivelul fișierelor de tip antet specifice limbajului Objective C.

Relații dintre ecranele aplicației se delimitează folosind identificatori de intenție numiți segue. Aceste relații se definesc la nivelul fișierelor antet, însă mecanismul de transfer între ecrane nu este unul automat, fiind necesară includerea unei secvențe de cod care face trecerea de la un ecran la altul.

V.2.1 Ecranul de autentificare

În momentul deschiderii aplicației, utilizatorul trebuie să introducă date valide în cadrul formularului de autentificare pentru a putea naviga la ecranul următor. La apăsarea butonului pentru autentificare, are loc testarea conexiunii către server iar datele introduse de utilizator sunt verificate și validate.

Dacă platforma web validează cu succes cererea provenită de la aplicația client, server-ul trimite un răspuns HTTP prin care se specifică câmpul token care va fi utilizat pentru marcarea viitoarele cereri înaintate server-ului.

În ceea ce privește structura interfeței, au fost adăugate două butoane principale prin care utilizatorul se poate autentifica sau poate să-și creeze un cont. Ambele butoane se folosesc de datele care au fost completate în cadrul câmpului „server”. Interfața ecranului de autentificare este prezentată în cadrul figurii V.2.1.1. Pentru a trece de procesul de autentificare, utilizatorul trebuie să completeze câmpurile corespunzătoare numelui de utilizator, parolei și adresei server-ului. De menționat este faptul că acel câmp care corespunde adresei server-ului a fost adăugat în cadrul aplicației doar cu scopul de a demonstra funcționalitate acesteia folosind o instanță a platformei care este rulată local.

Din punctul de vedere al implementării, în cadrul mediului de proiectare Storyboard, a fost adăugată o nouă scenă de tipul View Controller. Scena a fost marcată pentru a fi afișată în momentul în care este lansată aplicația.

Pentru această scenă numită Login View Controller au fost create și fișierele necesare implementării. Astfel, legăturile dintre elementele interfeței și variabilele create în cadrul codului sursă au fost definite în cadrul fișierului antet. Variabilele de tip IBOutlet reprezintă referințe spre elemente grafice din cadrul scenei iar metodele IBAction sunt utilizate pentru a executa secțiuni specifice din cod în momentele în care au loc interacțiunii ale utilizatorului asupra interfeței. Secvența următoare de cod ilustrează modul de definire al clasei principale care gestionează scena ecranului de autentificare:

@interface POLoginViewController : POViewController <POLoginModelDelegate, UIScrollViewDelegate>

@property (weak, nonatomic) IBOutlet UIImageView *backgroundImageView;

@property (weak, nonatomic) IBOutlet UITextField *usernameTextField;

@property (weak, nonatomic) IBOutlet UITextField *passwordTextField;

@property (weak, nonatomic) IBOutlet UITextField *serverTextField;

@property (weak, nonatomic) IBOutlet UIButton *loginButton;

@property (weak, nonatomic) IBOutlet UIButton *registerButton;

@property (weak, nonatomic) IBOutlet UIScrollView *scrollView;

@property (weak, nonatomic) IBOutlet UIView *contentView;

– (IBAction)onLoginButtonTouchUpInside:(id)sender;

– (IBAction)onRegisterButtonTouchUpInside:(id)sender;

@end

În momentul inițializării clasei principale din View Controller, se construiesc și referințele spre clasele de tip Model. Astfel, în cazul scenei curente, se inițializează clasa numită POModel.

Interacțiunile din partea utilizatorului sunt interceptate de clasa View Controller utilizând referințele adăugate anterior în fișierul de tip antet. Butonul de înregistrare va declanșa o secvență de cod care va deschid în navigatorul web implicit pagina corespunzătoare secțiunii de înregistrare a platformei web.

La o interacțiune din partea utilizatorului asupra butonului pentru procesul de autentificare, clasa principala a scenei va utiliza modelul și se va conecta la aplicația server printr-o conexiune HTTP a cărei adresă destinație va conține și datele extrase din câmpurile de text. Răspunsul primit de la aplicația server va reprezenta o structură de tip JSON. Secvența de text va fi decodată și se va face trecerea la ecranul următor dacă datele completate de utilizator au fost corecte. În cadrul răspunsului primit se specifică și un câmp token care va fi utilizat pentru a marca viitoarele cereri înaintate server-ului.

V.2.2. Ecranul principal

Finalizarea procesului de autentificare va transfera utilizatorul la scena meniului principal. Acest ecran are rolul de a facilita accesul direct sau indirect al utilizatorului la toate funcționalitățile oferite de aplicație. Astfel are loc o diferențiere a secțiunilor aplicației. Interfața meniului principal este surprinsă în cadrul figurii V.2.2.1.

Din punct de vedere structural, interfața acestei scene este alcătuită secțiunea antet, care include imaginea logo a aplicației, și o lista de secțiuni care vor răspunde interacțiunilor tactile.

Din meniul principal utilizatorul poate vizualiza direct categoriile corespunzătoare locațiilor, galeriilor și evenimentelor. Tot prin meniul principal utilizatorul poate fi redirecționat către adresa site-ului, poate efectua o căutare după cuvinte sau poate vizualiza un calendar al evenimentelor.

Din punctul de vedere al implementării, scena principală este construită folosind un element de tip Collection View care, totodată, permite specificarea structurii interfeței pentru elementele listei de butoane. Pentru scena MainCollectionViewController au fost create și fișierele necesare implementării. Astfel, legăturile dintre elementele interfeței și variabilele create în cadrul codului sursă au fost definite în cadrul fișierului antet. Structura scenei poate fi observată în cadrul figurii V.2.2.2.

Datorită structurii alese pentru această scenă, a fost necesară generare unei clase care extinde funcționalitatea oferită nativ prin UICollectionViewCell pentru a putea controla comportamentul fiecărei celule din lista principală. Astfel, în cadrul antetului acestei clase, s-au marcat referințele spre elementele interfeței. Următoarea secvență de cod ilustrează structura fișierului antet:

@interface POMainListCollectionViewCell : UICollectionViewCell

@property (strong, nonatomic) IBOutlet UIImageView *sectionIconImageView;

@property (strong, nonatomic) IBOutlet UILabel *sectionLabel;

@end

Navigarea la următoarele scene se realizează utilizând identificatori de intenție numiți segue. Excepția de la această regulă o reprezintă butonul denumit „Site Web” pentru care este lansată o nouă instanță a navigatorului implicit de pe dispozitiv. În cadrul procesului de inițializare a clasei sunt descrise elementele listei și corespondența acestora față de identificatorii de intenție. Secvența de cod utilizată a fost următoarea:

[self setSectionImageNames:[NSArray arrayWithObjects:@"button_menu_evenimente.png", @"button_menu_galerii.png", @"button_menu_localuri.png", @"button_menu_calendar.png", @"button_menu_cautare.png", @"button_menu_site.png", nil]];

[self setSectionNames:[NSArray arrayWithObjects:NSLocalizedString(@"Evenimente", nil), NSLocalizedString(@"Galerii", nil), NSLocalizedString(@"Locații", nil), NSLocalizedString(@"Calendar", nil), NSLocalizedString(@"Căutare", nil), NSLocalizedString(@"Platforma Web", nil), nil]];

[self setSectionActions:[NSArray arrayWithObjects:@"segue", @"segue", @"segue", @"segue", @"segue", @"link", nil]];

[self setSegueNames:[NSArray arrayWithObjects:@"loadEventCategoryListSegue", @"loadGalleryCategoryListSegue", @"loadLocationCategoryListSegue", @"loadCalendarSegue", @"loadSearchSegue", nil]];

Secvența de cod care gestionează navigarea la următoarele scene este următoarea:

-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {

if ([[self.sectionActions objectAtIndex:indexPath.row] isEqualToString:@"segue"]) {

[self performSegueWithIdentifier:[self.segueNames objectAtIndex:indexPath.row] sender:self];

} else if ([[self.sectionActions objectAtIndex:indexPath.row] isEqualToString:@"link"]) {

ă[UIApplication sharedApplication] openURL:[NSURL URLWithString:[[self.model configAPI] objectForKey:@"appSiteURL"]]];

}

}

V.2.3 Ecranul de vizualizare a locațiilor

Din cadrul meniului principal utilizatorul poate accesa secțiunea corespunzătoare locațiilor utilizând structura de navigare. Datorită numărului mare de locații care pot fi vizualizate s-a optat pentru un mecanism de filtrare a acestora utilizând categorii și liste de locații similare. Astfel, utilizatorul va alege o categorie de locații dintre cele disponibile, iar apoi va fi transferat la următorul ecran unde sunt lista locațiile dintr-o anumită categorie. Din cadrul listei, utilizatorul va selecta o locație pentru a vizualiza detalii suplimentare.

Această structură a fost realizată utilizând trei scene diferite, organizate într-o ierarhie pentru a menține logica navigării. Interfața scenelor de vizualizare a categoriilor și a locațiilor dintr-o categorie este surprinsă în figura V.2.3.1.

Din punct de vedere structural, interfața scenei categoriilor de locații este alcătuită din o secțiunea antet, care include imaginea logo a aplicației, și o lista de secțiuni care vor răspunde interacțiunilor tactile. Scena locațiilor individuale include imaginea corespunzătoare locației, precum și informații detaliate referitoare la date de contact sau legături interne, în cadrul aplicației, spre galerii și evenimente care au fost atașate prin platforma web.

Din punctul de vedere al implementării, în cadrul mediului de proiectare Storyboard, au fost adăugată două scene de tip View Collection pentru listele de locații și un View Controller pentru locații individuale. Pentru fiecare scenă au fost create și fișierele necesare implementării. Astfel, legăturile dintre elementele interfeței și variabilele create în cadrul codului sursă au fost definite în cadrul fișierului antet. Structura scenelor și legăturile dintre acestea pot fi observate în cadrul figurii V.2.3.2.

Pentru această secțiune, cererile trimise sistemului API vor include în cadrul adresei URL date suplimentare referitoare la categoria selectată de utilizator. Datele returnate de metodele native pentru gestionarea conexiunilor externe sunt decodate din formatul original JSON pentru a putea fi prelucrate. Modalitatea de conexiune la server și de prelucrare a datelor este evidențiată prin secvențele următoare de cod:

NSDictionary *parameters = @{

@"task": @"getLocations",

@"category_id": [@(categoryId) stringValue]

};

[self.downloadManager GET:self.getRequestURL parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {

dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

if (returnedData[@"id"] != [NSNull null]) {

[locationCategory setId:[(NSString *)returnedData[@"id"] integerValue]];

}

} failure:^(AFHTTPRequestOperation *operation, NSError *error) {

[self showErrorMessage];

}];

V.2.4 Ecranul de vizualizare a evenimentelor

Secțiunea aplicației corespunzătoare evenimentelor este accesibilă folosind meniul principal. Prin selectarea unei categorii, utilizatorul poate vizualiza o listă de evenimente. În cadrul secțiunii de vizualizare a evenimentelor, ecranul corespunzător listei de evenimente și categorii este în mare parte similar cu ecranul de listare a locațiilor. Diferența e reprezentată de prezența unor informații adiționale pentru fiecare eveniment. Astfel, în cadrul procesului de listare a evenimentelor s-au afișat în plus data de începere și numele locației.

Funcționalitatea de vizualizare a evenimentelor a fost implementată utilizând trei scene diferite, organizate într-o ierarhie pentru a menține logica navigării.

Din punct de vedere structural, interfața scenei categoriilor de evenimente este alcătuită din o secțiunea antet, care include imaginea logo a aplicației, și o lista de secțiuni care vor răspunde interacțiunilor tactile. Scena evenimentelor individuale include o imagine principală, intervalul orar în care are loc evenimentul și un scurt text care oferă informații suplimentare. În cadrul scenei unui eveniment, titlul locației este subliniat pentru a evidenția faptul că există opțiunea navigării spre pagina corespunzătoare acesteia. Structura scenei pentru vizualizarea evenimentelor este ilustrată în cadrul figurii V.2.4.1.

Similar implementării aplicației pentru sistemul Android, informațiile vizibile pentru un eveniment sunt:

numele evenimentului

numele locației

data de începere

imaginea de prezentare

descrierea dinamică (HTML)

Pentru a asigura o consistență în ceea ce privește implementarea, în cadrul mediului de proiectare Storyboard, au fost adăugate două scene de tip View Collection pentru listele de evenimente și un View Controller pentru evenimente individuale. Pentru fiecare scenă au fost create și fișierele necesare implementării. Astfel, legăturile dintre elementele interfeței și variabilele create în cadrul codului sursă au fost definite în cadrul fișierului antet.

V.2.5 Ecranul de vizualizare a galeriilor

Secțiunea corespunzătoare locațiilor se poate accesa din cadrul meniului principal utilizând structura de navigare. Datorită numărului mare de galerii si imagini care pot fi vizualizate s-a optat pentru un mecanism de filtrare a acestora utilizând categorii și liste de galerii similare.

Spre deosebire de interfețele prezentate anterior, secțiunea galeriilor prezintă o interfață de vizualizare a imaginilor din cadrul unei galerii. Astfel din cadrul ecranului de listare a galeriilor, prin selectarea unei galerii(figura V.2.5.1), se afișează fragmentul de listare a imaginilor. Structura acestei secțiuni este alcătuită din patru scene distincte, organizate într-o ierarhie pentru a menține logica navigării.

Din punct de vedere structural, interfața scenei categoriilor de galerii este alcătuită din o secțiunea antet, care include imaginea logo a aplicației, și o lista de secțiuni care vor răspunde interacțiunilor tactile. Scena galeriilor individuale include o lista de imagini, acestea având opțiunea de a fi salvate la o intervenție tactilă îndelungată a utilizatorului.

În ceea ce privește faza de implementare a funcționalității, în cadrul mediului de proiectare Storyboard, au fost adăugate trei scene de tip View Collection pentru listele de galerii și imagini, iar pentru vizualizarea imaginilor individuale s-a optat pentru folosirea unui View Controller.

Salvarea unei imagini din galeria curentă pe spațiul de stocare local s-a realizat prin utilizarea metodei native UIImageWriteToSavedPhotosAlbum. Secvența de cod responsabilă pentru salvarea imaginilor este următoarea:

(void)longPress:(UILongPressGestureRecognizer*)gesture {

[alertController addAction:

[UIAlertAction

actionWithTitle:NSLocalizedString(@"Yes", nil)

style:UIAlertActionStyleDefault

handler:^(UIAlertAction *action) {

UIImageWriteToSavedPhotosAlbum(

self.scrollView.imageView.image,

self,

@selector(image:didFinishSavingWithError:contextInfo:),

nil

);

[self setSaveAlertWindowShown:NO];

}

]

];

[self presentViewController:alertController animated:YES completion:nil];

}

}

V.2.6 Ecranul de căutare. Ecranul secțiunii calendar

Din cadrul meniului principal utilizatorul poate accesa secțiunile de căutare și calendar folosind structura principală de navigare.

Secțiunea de căutare diferă față de interfețele utilizate în celelalte secțiuni fiind alcătuită dintr-un câmp editabil, o serie de butoane pentru selecție categoriei și o listă de intrări care vor fi returnate de la platforma web prin sistemul API. Structura acestui ecran este ilustrată în cadrul figurii V.2.6.1

Întrucât funcționalitate de filtrare a galeriilor, locațiilor și a evenimentelor a fost implementată, la un anumit nivel, în cadrul ecranelor precedente, s-au optat pentru reutilizarea claselor de tip model și adăugarea micilor modificări pentru ca acestea să fie compatibile cu clasa View Controller utilizată în cadrul secțiuni de căutare.

Din punctul de vedere al implementării, în cadrul mediului de proiectare Storyboard, a fost adăugată o nouă scenă de tipul View Controller și s-a utilizat elementul nativ Search View pentru a construi parte de antet a scenei. Astfel, datorită utilizării elementului nativ, s-au specificat categoriile asupra cărora va rula algoritmul de căutare fără a fi nevoie de elemente grafice suplimentare.

Secvența următoare de cod ilustrează modul de construcție dinamic al adreselor URL specifice sistemului API:

if (categoryId != 0) {

parameters = @{

@"task": @"getGalleriesByCategory",

@"category_id": [@(categoryId) stringValue]

};

} else if (searchString != nil) {

parameters = @{

@"task": @"getSearchResults",

@"search_in": @"galleries",

@"search_text": searchString

};

}

În ceea ce privește ecranul secțiunii calendar, interfața este alcătuită din două butoane care comută elementele evidențiate în cadrul tabelului utilizat pentru a afișa calendarul.

Ziua curentă este marcată special în cadrul calendarului iar utilizatorul poate naviga prin glisare între lunile anului. La selectarea unei zile, are loc afișarea unei ferestre de tip dialog, unde sunt listate evenimente sau galerii.

Datorită filosofiilor de proiectare promovate de producător, a fost necesară introducerea unui sistem care să asigure preîncărcarea datelor din tabel în avans față de interacțiunile utilizatorului. Structura interfeței este ilustrată în cadrul figurii V.2.6.2.

Capitolul VI. Studiu comparativ. Asemănări și deosebiri între implementările aplicațiilor pentru Android și iOS

Dezvoltarea continuă în domeniul terminalelor mobile inteligente a dus la apariția unor sisteme de operare moderne, optimizate pentru a rula pe aceste dispozitive, iar dintre acestea, sistemele cu rata de adopție cea mai mare sunt Android, respectiv iOS.

Sistemul de operare Android a fost dezvoltat în jurul unui nucleu Linux și a fost conceput pentru a rula pe dispozitive mobile. Sistemul dezvoltat de firma Google prezintă o interfață bazată pe ideea manipulării directe de către utilizator, folosind gesturi tactile care permit interacțiunea cu elementele de grafică și cu obiectele prezentate pe ecranul dispozitivului. Fiind, în esență, un proiect cu sursă deschisă, sistemul de operare a fost preferat de marii producători de dispozitive mobile deoarece oferă un grad mare de extensibilitate, iar implementarea acestuia nu presupune alte costuri suplimentare.

Spre deosebire de sistemul de operare Android, iOS a fost dezvoltat de compania Apple cu scopul de a rula exclusiv pe structurile hardware ale dispozitivelor mobile proprii. Similar sistemului Android, interfața este bazată pe ideea manipulării directe de către utilizator, folosind gesturi tactile care permit interacțiunea cu elementele de grafică și cu obiectele prezentate pe ecranul dispozitivului. Fiind un sistem de operare optimizat doar pentru anumite combinații de componente hardware, rata de adopție a acestuia este strâns legata de popularitatea dispozitivelor pe care rulează.

VI.1 Procesul de inițializare al aplicațiilor

Aplicațiile client dezvoltate pentru a deservi platforma web se caracterizează prin funcționalități identice și aspecte grafice apropiate. Deoarece scopul acestei lucrări este acela de a compara cele două sisteme de operare amintite mai sus, s-a optat pentru o dezvoltare a aplicațiilor utilizând doar limbajele native fiecărui sistem. Astfel, a fost posibilă exploatarea avantajelor fiecărui sistem în parte, precum și evidențierea marilor dezavantaje și diferențe existente.

În cazul sistemului Android, alegerea a fost una evidentă prin folosirea limbajului Java. Utilizarea acestui limbaj de programare pentru dezvoltarea aplicației client se justifică prin faptul că sistemul de operare Android permite dezvoltarea de aplicații native doar în limbajul Java. S-a ales această opțiune în detrimentul altor limbaje sau platforme de dezvoltare comună datorită cerințelor de performanță; aplicația vehiculează în orice moment un număr mare de imagini, conexiuni către server și fire de execuție în paralel.

În cadrul sistemului de operare iOS, dezvoltarea aplicației client a fost posibilă prin utilizarea platformei de dezvoltare software XCode. Platforma facilitează dezvoltarea de aplicații iOS native oferind șabloane și clase de bază în timp ce ecranele specifice aplicațiilor pot fi structurate vizual folosind mediul StoryBoard, fiind posibilă definirea de interfețe optimizate doar pentru anumite categorii de dispozitive mobile.

O limită a platformei de dezvoltare XCode este dată de cerințele de sistem pentru a putea crea aplicații mobile, astfel, dezvoltarea de aplicații se poate întâmpla doar în cadrul sistemului de operare MacOS. Această abordare are însă și avantaje, deoarece simularea dispozitivelor mobile în cadrul sistemului de operare reprezintă un proces simplificat și mai rapid decât cel al competitorilor.

Deosebirile dintre modurile de a trata procesul de dezvoltare a aplicațiilor devin vizibile încă din faza incipientă prin modul de generare a proiectelor de bază.

În cadrul platformei Android Studio, crearea unui proiect nou presupune utilizarea unui utilitar incorporat care segmentează procesul în mai mulți pași elocvenți. Astfel, dezvoltatorul trebuie întâi să completeze data generale despre aplicației, cum ar fi numele pachetelor sau versiunea de Android pentru care se vor produce optimizări. Pasul următor oferă opțiunea de a folosi mai multe șabloane generale care, printre altele, oferă chiar integrarea cu servicii Web populare. Figura VI.1.1 ilustrează șabloanele prezente în cadrul platformei Android Studio.

Natura închisă a sistemului de operare iOS influențează inclusiv acest proces inițial de creație al aplicației. Procesul de inițiere este similar celui oferit de Android Studio, însă șabloanele oferite sunt într-un număr mult mai mic și integrează doar servicii externe oferite de producător. Figura VI.1.2. ilustrează procesul de creație al aplicaților în cadrul platformei XCode.

Diferențele de filosofie între cele două sisteme de operare sunt aparente și în modul de abordare al procesului de creare al interfețelor și al fișierelor de configurare.

Sistemul Android promovează limbajul XML atât pentru construcția fișierelor de configurare cât și a interfețelor. Avantajul în reprezintă faptul că structura este una standardizată și ușor de extins folosind cod provenit de la librării terțe. Marele dezavantaj care este introdus de această abordare este faptul că mediul de dezvoltare are o curbă de învățare mai dificilă pentru programatori, însă acest aspect este combătut, în mare parte, prin interfețe specializate.

Modul de abordare al platformei XCode este unul diferit. Fișierele de configurare sunt vizualizate implicit în modul grafic, în unele cazuri nefiind disponibilă opțiunea de a edita direct codul.

VI.2 Particularități ale interfețelor

În cadrul platformei Android Studio doar unele tipuri de documente de configurare beneficiază de interfețe grafice dedicate; utilizatorul poate oricând să comute între modul cod și modul grafic. Interfața grafică este suportată de fișiere care descriu: elementele de structură ale unei scene, aspectul elementelor grafice, cuvinte cheie pentru limbi multiple. Absența unor interfețe specializate se remarcă în special atunci când se definesc stilurile de sistem sau culorile specifice pentru o aplicație. În figura VI.2.1. se poate observa modul de definire al interfeței pentru un eveniment.

Controlul diferitelor stări în care se pot afla anumite elemente de interfață, cum ar fi butoanele sau elementele de formulare, se realizează utilizând fișierele XML dedicate fiecărui element în parte. În cadrul acestor documente se pot defini stiluri și animații suplimentare.

Un dezavantaj al schemei suportate de aplicațiile native Android este absența unei modalități simple de control a relațiilor dintre deferitele ecrane ale aplicației.

În cazul construcției interfețelor, modul de abordare în cadrul platformei XCode este unul diferit. Ecranele aplicației și relațiile dintre acestea sunt definite utilizând mediul StoryBoard. Ecranele reprezintă instanțe independente de clase care reprezintă scenele aplicației, iar legăturile dintre acestea se realizează utilizând identificatori de intenție numiți segue. În figura VI.2.2 se poate observa modul de defini a interfeței unui eveniment prin mediul Storyboard.

Abordările acestor platforme de dezvoltare pentru descrierea interfețelor au însă și numeroase similarități. Proprietățile elementelor prezente pe scenă pot fi alterate utilizând mediul grafic iar scenele pot fi vizualizate și simulate pe diferite combinații de dispozitive (figura VI.2.3).

În cadrul aplicațiilor dezvoltate în această lucrare s-a urmărit respectarea normelor de proiectare recomandate sau impuse de producătorii sistemelor de operare. Sistemul de operare Android a suferit schimbări de interfața majore la fiecare iterație a sa, în timp ce sistemul iOS a reușit să mențină un aspect relativ familiar în decursul anilor. Fiecare sistem impune, recomandă respectarea unor norme în ceea ce privește:

Poziționare butoanelor și a altor elemente interactive pe ecran

Culorile utilizate și contrastele aplicate

Efectele elementelor interactive și semnalare acțiunilor

Tipul sau durata animaților și fluiditatea interfeței

Simularea proceselor de încărcare

Utilizare elementelor implicite ale interfeței sau modalități de combatere a limitărilor de tip hardware

Aceste diferențe de abordare a interfeței se reflectă și în cadrul aplicațiilor dezvoltate. Astfel, aplicația dezvoltată pentru sistemul iOS include în plus o secțiune antet care prezintă butoane de navigare ce nu există la nivel hardware. Figura 1.2.4 ilustrează diferențele ce apar în antetul fiecărei scene.

Totodată, datorită lipsei unor metode simple de manipulare a elementelor de interfață, există componente native care nu pot avea un aspect modificat masiv sub sistemul iOS. Un astfel de exemplu se regăsește la nivelul paginii de căutare, aplicația iOS având butoane de comutare a categoriei curente care respectă stilul impus de producător.

VI.3 Analiza performanței

În cadrul implementării aplicațiilor client, utilizarea metodelor si a limbajelor native a asigurat un grad mare de performanță și de compatibilitate cu cele mai noi versiuni ale sistemelor de operare și în același timp, posibilitatea de execuție a aplicației pe un număr cât mai mare de dispozitive mobile.

Implementarea nativă a celor două aplicații dezvoltate în cadrul acestui proiect introduce un grad sporit de dificultate în ceea ce privește analiza performanței. Datorită optimizării fiecărei aplicații pentru a rula pe sisteme de operare diferite, în ecuație sunt introduse și eventualele perturbații cauzate la nivel software de sistemul de operare.

Inițial, a fost luată în calcul și varianta unei dezvoltări comune a unei aplicații care să ruleze pe ambele sisteme de operare, însă o analiză de performanță ar fi evidențiat doar diferențele la nivel hardware între dispozitive.

Analiza de performanță în acest caz presupune o marcare a timpul necesar pentru a prelua datele de la server, pentru a le decoda și pentru a afișarea informației pe ecran. Testul va fi rulat pe mai multe dispozitive și se vor testa paginile de gestiune a evenimentelor, galeriilor și locațiilor.

Există numeroși factori care trebuie luați în considerare și care pot afecta exactitatea rezultatelor. Astfel, la nivel hardware, pot exista probleme majore care influențează rezultatul și care sunt cauzate de:

Întârzieri la nivelul rețelei locale

Întârzieri la nivelul server-ului (interogări SQL, execuția codului PHP)

Întârzieri cauzate de calitatea semnalului primit de terminalul mobil

Diferențe de performanta intre terminalele mobile

Din punct de vedere software, trebuie luate în considerare următoarele probleme.

Existența optimizărilor la nivel software în ceea ce privește traficul web

Diferențe de performanță în ceea ce privește viteza de desenare pe ecran a elementelor de interfață

Prezența programelor în fundal care afectează performanța sistemului de operare

Astfel, cu scopul de a elimina cât mai multe variabile în ceea ce privește testarea performanței, s-a urmat următoarea procedură de testare. Aplicația server a fost lansată pe un sistem care rulează sistemul de operare Ubuntu 16.04 LTS pentru a elimina eventualele probleme de performanță cauzate de alte programe care rulează în fundal. Sistemul este apoi conectat la un router împreună cu fiecare terminal mobil în parte, poziționat in proximitatea dispozitivului router fără a exista posibilitatea conexiunii externe la Internet. În cadrul procesului de testare s-au utilizat atât dispozitive reale cat si simulate ( tabel VI.3.1). Mediile de programare oferite de dezvoltatorii sistemelor de operare mobile oferă posibilitatea simulării comportamentului unor dispozitive prestabilite folosind capabilitățile sistemului gazdă.

Valorile minime, maxime și medii corespunzătoare fiecărui test au fost obținute prin repetarea execuției de p ori (unde p = 10). Testarea timpilor necesari pentru a executa o operație s-a realizat prin generarea unor mesaje de tip log ce apar în consola platformelor de dezvoltare. Aceste mesaje conțin un identificator numit timestamp care este raportat de sistem și are o precizie de 1 milisecundă.

Datele din tabelele următoare au fost calculate utilizând următoarea formulă pentru fiecare pas al execuției:

Rezultatele obținute au fost următoarele pentru procesele de inițializare a conexiuni la server, primirea datelor și decodarea acestora(tabele VI.3.2, VI.3.3, VI.3.4).

Analiza performanței aplicațiilor se poate realiza și utilizând unelte native oferite în cadrul platformelor de dezvoltare, însă scopul principal al acestora este de a detecta din timp probleme majore ce pot apărarea în cadrul codului sursă.

Menținerea unui număr mare de referințe sau omiterea unui mecanism de marcare a obiectelor care nu mai sunt utile reprezintă erori de proiectare care vor deveni vizibile în cadrul graficului de monitorizare al memoriei. Astfel, o proiectare ineficientă va cauza creșterea în timp a cantității de memorie rezervată aplicației și va afecta eficiența mecanismului numit garbage collection care asigură eliminarea referințelor absolute.

Realizarea unui număr mare de operațiuni complexe în cadrul firului de execuție principal va cauza probleme de performanță care vor fi vizibile în graficul de monitorizare al utilizării procesorului și totodată, în cadrul graficului corespunzător numărului de cadre generate de sistem în fiecare secundă.

În figura VI.3.4 sunt ilustrate graficele de performanță pentru aplicația curentă care rulează nativ în cadrul sistemului de operare Android.

Capitolul VII. Concluzii

Utilizarea tehnologiilor de ultimă generație a avut ca și consecință dezvoltarea unei platforme moderne care se caracterizează prin performanță, rapiditate și o interfață ușor accesibilă utilizatorilor.

Separarea logică a aplicației în cele trei mari părți componente a permis o dezvoltare axată pe categorii diferite de utilizatori. Astfel, în timp ce accentul cade pe promovarea evenimentelor pentru utilizatorii comerciali în cadrul platformei Web, obiectivul se schimbă atunci când este vorba despre aplicație mobilă. Aici se urmărește permiterea accesului unificat la liste de locații și evenimente pentru utilizatori.

În cadrul procesului de implementare a aplicaților native s-a optat pentru utilizarea limbajelor de programare native. Această abordare a avut rolul de a evidenția numeroasele diferențe ce apar în cazul implementării de funcționalității similare optimizate pentru sisteme de operare diferite. Diferențele dintre modurile diferite prin care sistemele de operare iOS și Android propun realizarea de interfețe mobile s-au putut observa și la nivelul aplicaților dezvoltate. Astfel, unele elemente de interfață cum ar fi secțiunea calendar sau butoanele de comutare, au utilizat filosofi de proiectare complet diferite.

Analiza de performanță a celor două aplicații mobile a evidențiat mici diferențe în ceea ce privește timpii de execuție. Astfel din punctul de vedere al componentelor hardware, terminalele care au rulat sistemul de operare Android au avut parte de intervale de execuție mai mici, însă, marele dezavantaj a fost reprezentat de performanța desenărilor pe ecran. În contrast, sistemul iOS a avut nevoie de un timp mai îndelungat pentru a procesa obiecte, însă desenarea elementelor grafice pe ecran a reprezentat un proces mult mai rapid.

Din punctul de vedere al implementării aplicațiilor mobile și a modului de testare a performanței, există un număr de îmbunătățiri care pot fi aduse, printre care se numără și:

Analiza unei implementări utilizând limbajul Swift pentru aplicația nativă iOS

Introducerea de optimizări în ceea ce privește interfața, existând deocamdată anumite elemente de interfață pentru care producătorii sistemelor de operare sugerează abordări diferite

Introducerea analizei performanței per nucleu. Datorită modului în care au fost tratate operațiile asincrone în cadrul aplicațiilor, model de testare actual va favoriza terminalele mobile care dispun de un număr mai mare de nuclee fizice la nivelul procesorului.

Bibliografie

[1] Larry Ullman (2008) : PHP și MYSQL pentru site-uri web dinamice – Editura Teora

Bibliografie electronică

Similar Posts