/it2810-webutvikling-h18-prosjekt-3-14

it2810-webutvikling-h18-prosjekt-3-14 created by GitHub Classroom

Primary LanguageJavaScript

it2810-webutvikling-h18-prosjekt-3-14

Introduksjon

Vi har utviklet en skritteller, hvor brukeren får en personlig oversikt over antall skritt tilbakelagt per dag, samt en ukebasert oversikt over antall skritt tilbakelagt. Brukeren oppgir et mål for antall skritt per dag, og applikasjonen gir deretter kontinuerlige oppdateringer om statusen på det gitte målet gjennom et tilpasset brukergrensesnitt. Applikasjonen estimerer lengden tilbakelagt og kalorier forbrent basert på en rekke parametere brukeren skriver inn - alder, vekt, høyde og kjønn. Brukeren får også tilbakemelding om målet oppgitt for antall skritt er nådd eller ikke. Dermed blir applikasjonen et pedometer basert på personlig informasjon med hensikt å motivere brukeren til å bevege seg mer - derav det kreative applikasjonsnavnet Walktrue.

Opprette/Redigere bruker

I applikasjonen er det lagt til rette for at brukeren skal kunne opprette en bruker første gang man åpner appen. Brukeren oppgir da informasjon som navn, alder, kjønn, høyde og vekt som senere blir brukt for å utføre beregninger av tilbakelagt distanse og kalorier forbrent basert på BMI. Dataen brukeren oppgir blir lagret i Async Storage ettersom dette var et krav i oppgaven. Brukeren trenger dermed kun å oppgi informasjonen første gangen applikasjonen tas i bruk, data oppgitt av brukeren og tilhørende brukerhistorikk vil være tilgjengelig gjennom Async Storage lokalt på hver enhet som kjører applikasjonen.

Async Storage

I oppgaven ble det stilt krav om å benytte Async Storage for lagring av data. Async Storage er et enkelt lagringssystem som fungerer globalt innad i en applikasjon, det erstatter på mange måter local storage som man vanligvis benytter for å oppbevare tokens for å holde brukersesjoner i lengre perioder i React. Hver metode i Async Storage sitt API returnerer et Promise-object, altså et objekt som representerer en fullført (eller feilet) operasjon og den resulterende verdien. I denne applikasjonen har vi benyttet metoder som setItem() og getItem(), metoder som henholdsvis oppretter og henter data fra minne asynkront. Som nevnt benytter vi Async Storage til å lagre personlig brukerdata og tilhørende brukerhistorikk som antall skritt tilbakelagt den siste dagen og uken - videre også metadata beregnet ut i fra disse dataene; for eksempel et estimat av antall kalorier forbrent.

Daglig oversikt

Den daglige oversikten gir deg en oversikt over hvordan du ligger ann i forhold til ditt satte daglige mål. Brukerens info blir først hentet ut fra Async Storage, hvor det så blir prosessert i hjelpefunksjoner som gir ut data som er interessant for brukeren. Antall skritt mot mål blir vist i en ‘Animated Circular Progressbar’, og distanse gått, kalorier forbrent og din nåværende BMI blir vist som tekst. Distansen blir regnet ut ved hjelp av brukerens skrittlengde basert på høyde og regner ut et ca. anslag på distanse. Denne distansen brukes også når man regner ut kalorier. Denne utregningen blir gjort ved å anta at brukeren går i gangfart den tiden han beveger seg, og da bruke dette til å anta et kaloriforbruk. BMI blir regnet ut ved hjelp av standard BMI-formel. I øverste venstre hjørne er det mulighet for å klikke seg inn for å redigere brukerens info. Dette gjøres i en Stack Navigator, som gjør at brukeren enkelt kan enten velge å oppdatere informasjon, eller navigere seg tilbake til den daglige oversikten. Brukeren kan også fritt navigere seg til enten den ukentlige oversikten eller profiloversikten, uten at redigeringsskjermen forsvinner. Hvis en redigering blir gjennomført, så sendes det ut et event om at info er oppdatert. I den daglige oversikten ligger det en Event listener - når et oppdateringsevent blir oppdaget vil denne hente inn den nyeste informasjonen fra AsyncStorage

Ukentlig oversikt

Den ukentlige oversikten viser noe av den samme statistikken som den daglige oversikten, bare på et ukentlig scope. Videre har denne skjermen et søylediagram som tydelig visualiserer den ukentlige til skrittelleren. Det er opp til syv søyler, en for hver dag siden mandag, som viser skritt tatt den dagen. Man kan også trykke på søylene for å få mer presise tall på den valgte dagen. Mye av implementasjonen likner på dag-skjermen, og mange av de samme hjelpefunksjonene blir brukt. Men på denne skjermen bruker vi “react-native-pure-chart”, en graf implementasjon til react native som kun bruker standard komponenter, for å vise statistikk over uken. For å finne relevant data til søylediagrammet itererer vi over alle dager mellom mandag, og dagen i dag, og konstruerer en state som har riktig struktur for graf implementasjonen.

Profiloversikt

Inne på profilen er det en Card-komponent som visualiserer en kombinasjon av dataen brukeren har tastet inn og status på målene som er oppgitt basert på progresjon målt av pedometeret. All informasjon som vises i profiloversikten er hentet eller basert på data hentet fra Async Storage. Profiloversikten er inkludert for å gi brukeren mulighet til å se informasjonen oppgitt uten å måtte navigere gjennom redigeringstaben, samt også for å personalisere progresjonen mot det oppgitte målet.

Komponenter

Vi har benyttet en rekke standardkomponenter fra React Native biblioteket, nedenfor forklares det eksplisitt hvordan de mest sentrale i applikasjonen er implementert og skal være dokumentert som et slags tutorial.

  • Pedometer Dette er en komponent som holder oversikt over antall skritt vandret - på android kobler den seg opp mot Google Fit og på iOS brukern den Core Motion. Vi har implementert pedometeret på en måte som gjør at man får en oversikt over antall skritt per døgn, videre har vi lagd en oversikt over antall skritt per dag på ukesbasis - dette visualiseres gjennom Weekday. Pedometeret er implementert både i Weekday og i Today, vi har benyttet komponenten på en måte som gjør at det enkelt skal være mulig å kunne se linjer mellom vår implementasjon og den fra expo sin egen dokumentasjon.

  • TextInput Vi benytter TextInput for å innhente nødvendig informasjon ved oppretting og redigering av bruker. Informasjonen brukeren skriver inn i TextInput blir fortløpende satt til state i komponenten. Deretter lagres informasjonen i Async Storage ved å trykke “Submit/Save” - ved å trykke på knappen kalles en funksjon som lagrer tilstanden til komponenten som et eget objekt i AsyncStorage. TextInput tar imot en rekke props som definerer formatet i form av for eksempel tekst eller en number-pad. For å gjøre det enkelt for brukeren å forstå at det er et tall som skal skrives inn, har vi tilpasset formatet på textinputen basert på hva som aksepteres av input. Spesifikt har vi definert keyboardtype som number-pad og numeric, dette forsikrer at brukeren eksempelvis ikke skriver desimaltall på alder - et inputfelt som kun skal akseptere positive heltall. De eneste valideringen av brukerinput vi selv er nødt til å foreta oss da er forsikring om at tallene som skrives inn er større enn 0. Knappen for å lagre eller opprette brukeren er deaktivert helt frem til alle inputfeltene er fylt ut med aksepterte verdier. Dette gjør at funksjonalitet videre i Applikasjonsstrukturen ikke trenger å ta hensyn til om data som skal behandles matematisk er av riktig type og størrelse- å sentralisere validering av brukerdata er hensiktsmessig da det gjør det enklere og kjappere å oppdage eventuelle feil og å enkelt kunne innføre nye restriksjoner ved innføring av ny funksjonalitet i applikasjonen.

Routing

Dokumentere hvordan vi har løst navigasjon mellom forside og de ulike tabsene. For å håndtere navigasjonene mellom de ulike skjermene i applikasjonen benytter vi en viderebygging av strukturen man kan initiere ved opprettelse av React Native-prosjektet. Dette baserer seg på et konsept hvor vi her en hoved navigator, i vårt tilfelle AppNavigator som switcher gjennom ulike stacker, hvor hver enkelt stack gjerne utgjør en eller flere screens i applikasjonen. Første gangen applikasjonen blir kjørt blir brukeren send til ruten definert som initialRouteName, i vårt tilfelle da AuthLoading - dette navigerer altså brukeren til AuthLoadingScreen. Der sjekker applikasjonen om det eksisterer en spesifikk bruker i AsyncStorage, dersom den ikke finner noen bruker blir man sendt til siden for å registrere en - hvis det derimot eksisterer en bruker fra før blir man sendt direkte inn i applikasjonen. Funksjonen _bootstrapasync() sørger for at sistnevnte operasjonen blir gjennomført ved initialisering av AuthLoadingScreen. Navigatøren til applikasjonen får altså beskjed om hvilken screen den skal switche til, og påfølgende rendres korrekt screen med tilhørende komponenter på skjermen. Hver enkelt screen fungerer på mange måter som en SPA, bare at vi har flere SPA-er i dette tilfellet som deler data lokalt gjennom Async Storage. Vanligvis vil det kun være naturlig å lagre token for brukeren i AsyncStorage, og heller ha en ekstern database for å lagre faktisk brukerdata.

Testing

Vi utfører flere typer tester. For det første bruker vi jest for å unitteste blant annet det meste vi har av hjelpefunksjoner. Videre bruker vi snapshot testing for å teste både komponenter og screens. Vi har også foretatt tester på våre egne mobiler. Det innebærer både Android og iOS. Samt testing på store skjermer som iPhoneX eller OnePlus6, samt mindre skjermer som eldre iPhones. Vi har også testet på en nVidia Shield tablet.

Kilder:

TextInput: https://facebook.github.io/react-native/docs/textinput