I følgende prosjektet har vi laget en Personal Information and Motivation Manager-applikasjon. App-en er basert på enkelhet og inneholder funksjonalitet for:
- Skritteller
- Dagens mål / dagens motivasjon
- Gjøremål-app
- Tilpassing av app-en til dag- eller natt-tema.
App-en består av tre screens som kan byttes mellom ved hjelp av navigasjonsfaner, også kalt tabs.
Løsningen vi valgte for tabs var via ‘react-navigation’
-biblioteket. Dette gir oss muligheten til å lage en tab-bar etter egne spesifikasjoner ved å mate inn et JSON-objekt når tab-en initialiseres. Her brukes da createBottomTabNavigator()
-funksjonen.
Asyncstorage har vi implementert i fila utils/localstorage.js
. Her har vi to funksjoner som kan brukes – saveData
og loadData
. saveData
tar inn data
som skal lagres, og hvilken key
dette skal lagres på. loadData
tar kun inn en key
, der dataen skal hentes opp fra. loadData
returnerer et promise når den blir kjørt, så denne krever at man håndterer det riktig. Dette er en veldig enkel implementasjon, og ville hatt noen utfordringer dersom det skulle brukes i produsjon. For eksempel sjekkes det ikke om nøkkelen eksisterer, og nøkkelen trenger ikke være på et visst format. Hvilket som helst sted koden kan man også lagre og laste til localstorage. Dette kan medføre sikkerhetsproblemer, ettersom at state kan endres på denne måten. Disse problemene er enkle å fikse, men vi gjorde ikke noe med det i denne omgang, ettersom appen kun skulle ha nødvendig funksjonalitet.
For Todo-appen vår brukes ‘react-native-elements’
til å sette opp selve listen med gjøremål. Dette da biblioteket gjør det enkelt å legge inn ikoner i listeementet på en god måte. Ved dette fikk vi muligheten til å bruke Icon
fra samme bibliotek som prop (leftIcon
etc.) i ListItem
. Ellers er alle andre bibliotek enten fra ’react’
eller ‘react-native’
.
Goal – som ligger under skrittelleroversikten i HomeScreen
– består av en DailyGoalContainer
(heretter Container
), som igjen inneholder et DailyGoalForm
(heretter Form
). I tillegg til å inneholde et Form
ligger tekstpresentasjonen i Container
, som viser hvilket mål som er det gjeldende målet. Dersom det ikke finnes et mål i localstorage og brukeren ikke har satt et mål enda, vil dette målet være en standardmeling. Om det finnes et mål i localstorage blir det vist. Ved å skrive inn et nytt mål og legge til dette, blir det gamle målet skrevet over i localstorage, og det nye målet blir presentert. Det er også en knapp for å fjerne målet sitt. Da blir målet fjernet i localstorage også. Implementerte først funksjonalitet for å ha flere mål samtidig, men dette ble ikke med i den siste versjonen.
Pedometer
-komponenten henter inn skrittdata fra asynkron lagring (hvis tilgjengelig). Dette hentes fra mobiltelefonens helsedata, enten det er iOS eller Android. MERK dette vil derfor ikke fungere hvis en bruker en emulator på datamaskin, da det ikke er noe data tilgjengelig å hente her, men vil fungere ved testing på mobil. Appen vil kunne kjøre på emulator, men du vil ikke få opp noen tall for skrittdata.
Vi valgte å utforske pedometer (skritteller) teknologi. Vi brukte Pedometer
-komponenten som er en del av expo sitt eget bibliotek. Vi fulgte eksempelet på expo sine egne nettsider: https://docs.expo.io/versions/latest/sdk/pedometer for å implementere pedometeret i appen vår. Deretter la vi til noen funksjoner selv for å generere skrittmål, og regne ut hvor langt man var kommet på vei til målet. I tillegg lagde vi funksjoner som endret litt på styling i appen (farger) basert på antall skritt gått de siste 24 timene sammenlignet med målet som er satt av brukeren. Vi valgte også denne fordi det kan bidra positivt med motivasjon i en “Personal Information and Motivation Manager”.
Under ligger en fremgangsmåte for å implementere pedometerteknologien i ditt prosjekt. Det er gjort følgende antagelser om brukerens forkunnskaper:
- Brukeren vet hvordan man setter opp en react-native component
- Brukeren importerer det som trengs for å lage en react-native component
- Brukeren bruker asyncStorage og kan hente og lagre data ved hjelp av dette
- Importer
ProgressCircle
fra‘react-native-progress-circle’
- Importer
Input
fra‘react-native-elements’
- Opprett en javascript fil
- Importer
Pedometer
fra'expo'
- Opprett en klasse slik som i kode-eksempelet i linken til expo sine sider.
- I tillegg til det som er i deres eksempel må du legge til:
State
:stepcountGoal
(for å lagre målet brukeren har satt seg)inputText
(for å lagre målet brukeren taster inn fra Inputkomponent)
- I
componentDidMount()
:- Når komponenten mounter må vi hente data fra AsyncStorage, her må du laste inn data fra samme
key
som du lagrerstepcountGoalet
ditt på. Eks: “stepCountGoal
” - Ellers husk å inkluder
_subscribe
funksjonen som er med i kode-eksempelet til expo.
- Når komponenten mounter må vi hente data fra AsyncStorage, her må du laste inn data fra samme
componentWillUnMount()
forblir uendret- Vi har lagt til en funksjon som heter “
updateStepGoal()
”.- Du må ha en funksjon som sjekker hva som er skrevet i input komponenten i samme screen som pedometeret ditt. Den må deretter oppdatere state (
stepcountGoal
) til å bli det som er skrevet iinputText
. Husk å ha sjekker for at det er et gyldig mål som er skrevet inn. - Denne funksjonen skal kalles når en trykker på en knapp på skjermen, nevnt lengre ned i denne fremgangsmåten.
- Denne funksjonen må også oppdatere det som er lagret i AsyncStorage på keyen du har valgt deg for
stepcountGoal
- Du må ha en funksjon som sjekker hva som er skrevet i input komponenten i samme screen som pedometeret ditt. Den må deretter oppdatere state (
_subscribe()
fra expo forblir uendret (denne funksjonen lytter etter endringer i stepcount fra iOS Core Motion eller Android Google Fit- Du må ha en funksjon som regner ut prosentandel av skrittmålet som er oppnådd. Vi har kalt denne for “
getProgressPercent()
”.- tar inn state-verdiene for
pastStepCount
og dividerer påstepGoal
. Deretter har vi bruktMath.floor
for å runde tallet ned til nærmeste prosent. Denne kan brukes for å ha dynamisk styling basert på skrittene som er gått i forhold til skrittmål.
- tar inn state-verdiene for
- Du må ha en funksjon som returnerer en fargeverdi basert på prosenten regnet ut av “
getProgressPercent()
” beskrevet over.- Eventuelt bare regn ut prosenten i funksjonen i seg selv, gjør som over, ta inn state sin
pastStepCount
og divider påstepGoal
, deretter returner forhåndsbestemte fargeverdier basert på hva resultatet blir. - Kall denne funksjonen i
render()
funksjonen din, og sett fargen til en const som du kan kalle istyle={foo}
for å endre farger i pedometeret ditt.
- Eventuelt bare regn ut prosenten i funksjonen i seg selv, gjør som over, ta inn state sin
- I
render()
må du inkludere enInput
-komponent og enProgressCircle
komponent. - I
render
må du returnere enProgressCircle
som brukergetProgressPercent()
for å regne ut hvor mye av sirkelen som skal farges, og som har tekst i seg som skriver ut antall skritt man har gått siste 24 timer fra state sinpastStepCount
. - I render må du ha en
Input
komponent som påonChangeText
kallersetState
og dermed endrer state sin verdi forinputText
. - I render har vi også en
button
som brukes for å kalleupdateStepGoal()
som da bruker state sininputText
til å oppdaterestepGoal
. - Dette er altså alt du må inkludere for å oppnå VÅR implementasjon av teknologien. En kan returnere hva man vil i render, og
Pedometer
fra expo stiller ingen krav for ting som må returneres i render. - OBS: Man vil bli bedt om å gi appen tillatelse til å hente data fra iOS Core Motion, som vil hente fra helse-appen. Man vil kunne bli bedt om det samme på android Google Fit. Tillater man ikke dette, vil ikke pedometer finne noe lagret data, og det vil da ikke fungere. Det vil bli skrevet i appen at den ikke finner noe asynclagret data for skritt. Derfor vil det ikke fungere å teste i emulator heller.
Vi har forsøkt å bruke Jest
til å teste applikasjonen vår, slik som det var nevnt i oppgavebeskrivelsen. Vi har hatt store problemer med Jest, og vi får ikke testet state. Dette er en stor ulempe ettersom alt i appen vår bruker state for å regne ut hva som skal sendes til skjermen. Som resultat av dette er all vår testing gjort med snapshot-testing (link til snapshots her: https://github.com/IT2810/it2810-webutvikling-h18-prosjekt-3-13/tree/master/coverage/lcov-report/it2810-webutvikling-h18-prosjekt-3-13) av hvordan hver komponent rendrer. Dette møtte vi også store problemer med, med tillegget ‘react-navigation’
, ettersom at vi ikke fant ut hvordan vi skal få laget snapshots som tester alle ‘tabs’ i appen. Resultatet av dette er lav code coverage i testingen.
Ettersom vi ikke bruke Enzyme har vi ikke fått testet skikkelig om callback-funksjoner fungerer. Vi har forsøkt mocking, men til lite nytte, så vi droppet det til syvende og sist.
Hvis vi hadde fått jest og mocking til å fungere bedre ville vi ha sørget for å enhetsteste alle funksjoner. Vi ville testet hver del av koden (alle funksjoner), og forsøkt å teste flere deler av koden samtidig. Vi ville passert inn verdier som er forventet, samt ikke forventede verdier. Vi ville testet verdier som er alt for høye, alt for lave (negative) samt 0, ettersom disse verdiene ofte kan føre til feil. Vi ville også prøvd å passere inn paramtere som er av feil type, som bool til noe som forventer string etc.
Ellers har vi kontinuerlig gjennom utviklingen av appen testet builden på både iOS gjennom Xcode sin emulator, og gjennom iPhone i virkeligheten og på to android telefoner i virkeligheten.
Git clone
i valgfri mappe på datamaskinen din.- Endre directory slik at du befinner deg i
it2810-webutvikling-h18-prosjekt-3-13
- mappen.- Her må du kjøre
npm install
- Deretter kjør
expo start
- Da skal du få opp Metro Bundler ready i browseren din.
- Her må du kjøre
- Kjør nå appen gjennom mobilen din med beskrivelsen under:
Hvis du ønsker å prøve å appen gjennom expo på mobil må du sørge for å bruke QR-kode scanneren på android-telefonen din når du laster inn appen, hvis ikke vil ikke alltid async loading av steps fra telefonen sine helse-data fungere ordentlig.
For å kjøre på iPhone kan du bruke kamera applikasjonen (som er i iOS fra før av) til å scanne QR-koden, den telefonen din skal da la deg åpne expo, og kjøre appen. Hvis ikke: send en mail/sms til deg selv gjennom nettleseren din og metro bundler. Åpne deretter mailen/sms på mobilen din, og åpne appen i expo gjennom linken i mail/sms.
Du kan også kjøre på emulator på datamaskinen, men da vil det ikke være noe tilgjengelig data for skrittelleren, og du vil derfor ikke få full funksjonalitet i appen.
Her er Gif-filer som raskt viser hvordan appen ser ut, og det meste av funksjonaliteten i appen.
Kilder:
- Inspirasjon til Todo-liste: https://hellokoding.com/todo-app-with-react-native/
- React-native-navigation: https://reactnavigation.org/docs/en/tab-based-navigation.html
- Trenger følgende npm installasjon:
'npm install --save react-navigation'
- Trenger følgende npm installasjon:
- Expo sin pedometer-komponent: https://docs.expo.io/versions/latest/sdk/pedometer