Deling av data med bevegelser Thump Matching

Velkommen til del III av Delingsdata med Gestures-serien. I del II opprettet vi vår mellomliggende serverprosess i Ruby on Rails. Denne serverprosessen vil fungere som en kanal mellom to enheter som prøver å kommunisere med en gest, vi kaller en "thump". Når to enheter er "thump" - sammen, vil serveren matche dem ved å beregne deres nærhet til hverandre gjennom GPS koordinater, så vel som en nesten identisk tidsstempel når de åpnet kommunikasjon med serveren. Når denne kampen er utført, vil serveren utveksle meldingene som er skrevet i mobilappen, og simulere kommunikasjonen mellom enhet og enhet.

I del III vil vi distribuere vår server-app til heroku-plattformen og deretter oppgradere vår mobilapp for å kommunisere med den.

For å starte, vil vi modifisere vår overslags tabell migreringsfil for å være kompatibel med Postgres. Du kan finne denne filen i katalogen "db / migrate", og den vil bli oppkalt noe som: TIMESTAMP_create_thumps.rb. Den enkleste måten å distribuere en heroku-app på er å bruke sin felles database tjeneste, som skjer med Postgres i stedet for MySQL. Vi skal erstatte følgende linjer:

 t.decimal: lat,: presisjon => 8,: skala => 8 t.decimal: lng,: presisjon => 8,: skala => 8

med disse nye linjene:

 t.decimal: lat,: skala => 8 t.decimal: lng,: skala => 8

Postgres håndterer store desimalfelt annerledes enn MySQL gjør, så dette er en nødvendig endring for å sikre at vi får datapoint-presisjonen vi trenger i våre breddegrad og lengdegrad felt.

Siden dette er en Rails 2.3.5 app, vil vi utnytte den eldre heroku-metoden for å installere edelstener ved å lage en .gems-fil i roten til vårt Rails-prosjekt. De fleste av dere vil nok være vant til å bruke Bundler for denne typen oppgave, men siden Geokit-pluginet ikke er oppgradert til å være Rails 3.0-kompatibelt, må vi gjøre ting med de eldre Rails 2-konvensjonene.

Vi legger ganske enkelt til følgende i vår .gems-fil:

 skinner -v 2.3.5 pg geokit --versjon '= 1.5.0'

Her spesifiserer vi skinnene perle og versjon vi bruker for dette prosjektet, samt postgres perlen, og versjon 1.5.0 av geokit perlen.

Nå kan vi begynne vår distribusjon! La oss starte med å opprette et lokalt git-repository inne i prosjektet vårt. Alt vi trenger å gjøre er å kjøre følgende kommando i rotkatalogen av vårt Rails-prosjekt:

 $ git init

Før vi forplikter oss til dette depotet, trenger vi å lage vår app på heroku-plattformen. Hvis du ikke har registrert deg for en gratis heroku-konto ennå, gjør du det ved å bare registrere deg på https://api.heroku.com/signup. Hvis du ikke har heroku-perlen installert på systemet, kan du gjøre det ved å kjøre følgende kommando:

 $ sudo perle installere heroku

Når perlen er installert, kjør følgende kommando fra innsiden av rotkatalogen av prosjektet:

 $ heroku skape - stakk bambus-ree-1.8.7

Her spesifiserer vi bambus-ree-stakken på grunn av at dette er en Rails 2-app. I tilfelle at du nettopp har opprettet en ny konto, kan det hende at du spørre om din legitimasjon for din heroku-konto. Når de er oppgitt, blir disse legitimasjonene lagret for fremtidige samhandlinger med heroku-serverne. Hvis alt går bra, bør heroku svare med noe som følger:

 Opprettet http://APPNAME.heroku.com/ | [email protected]: APPNAME.git Git Remote Heroku lagt til

Her har jeg erstattet det aktuelle programnavnet og underdomenet med en plassholder som heter APPNAME. Vær oppmerksom på denne APPNAME som vi vil bruke den senere. Nå skal vi forplikte våre prosjektfiler til det lokale git-repository vi opprettet tidligere. Det er så enkelt som å kjøre disse to kommandoene:

 $ git add. $ git commit -m "min første commit"

Når prosjektet har vært fullt forpliktet til lokal git repo, må vi skyve det til fjernregisteret som ble opprettet da vi kjørte kommandoen heroku create.

 $ git push heroku master

Heroku-perlen lar deg utføre eksterne rake-kommandoer på serveren med kommandoen "heroku rake". For å fullføre distribusjonen må vi kjøre våre databasemigrasjoner som vil generere vårt bunkebord i heroku-databasen.

 $ heroku rake db: migrere

Gratulerer! Du har implementert vår thump server applikasjon på heroku plattformen. Nå tilbake til mobilappen!

La oss åpne vår main.lua-fil i vår Corona-app og legge til følgende linjer øverst:

 http = krever ("socket.http") ltn12 = krever ("ltn12") url = krever ("socket.url") krever ("Json")

Vi må kreve noen biblioteker som gjør det mulig for oss å skape en stikkontakt til serverprogrammet vårt. Vi vil også inkludere JSON-parsing-biblioteket slik at vi kan forstå svarobjektene serveren vil sende tilbake.

Husk APPNAME som ble gitt da vi først opprettet heroku-appen? Det er på tide å bruke det nå:

 lokal appname = "APPNAMEHERE"

Denne variabelen vil bli kombinert med andre senere for å generere vår serveradresse for ekstern kommunikasjon.

I del I hadde vi appen som viste en varselboks med meldingen vår da den oppdaget en "thump" eller shake gest. Siden vi må kommunisere denne meldingen til serveren, fjerner vi den følgende linjen fra vår getThump-funksjon:

 lokalvarsling = native.showAlert ("Thump!", "Location:"? latitudeText? ","? longitudeText? "\ r \ nMessage:"? textField.text, "OK")

Nå skal vi legge til noen funksjonalitet til denne getThump-metoden for å sende meldingen til serveren. La oss bryte dette ned:

 lokal melding = textField.text local post = "thump [deviceid] ="? DeviceID? "& Dunk [lat] ="? latitudeText? "& Dunk [lng] ="? longitudeText? "& Dunk [melding] ="? melding lokal respons = 

Her genererer vi våre variabler for å sende til serveren. "Post" -variabelen er satt opp i spørringsstrengformatet, og vårt "svar" er erklært som et tomt tabellobjekt for nå.

 lokal r, c, h = http.request url = "http: //"? APPNAME? ".heroku.com / thumps", metode = "POST", overskrifter = ["innholdslengde"] = #post, ["Content-Type"] = "application / x-www-form-urlencoded", kilde = ltn12.source.string (post), sink = ltn12.sink.table (respons) lokal jsonpost = Json.Decode (table.concat (response, "))

Her utfører vi en HTTP-forespørsel av typen POST til serveren vår. Vi er subbing i vår appnavn variabel som underdomene for webadressen. Overskriftene er standard for et vanlig innlegg. I feltet "innholdslengde" vil lua-syntaksen for å sette en # foran variabelen, sende lengden i tegnene til den aktuelle strengen. Siden vi vil lagre serverens repsonse i en variabel som kalles "respons", vil vår siste linje dekode denne variabelen som et JSON-objekt og opprette et lua-tabellobjekt, slik at vi kan få tilgang til felt innenfor det.

I tilfelle en kommunikasjonsfeil må vi varsle brukeren om at noe har gått galt. Vi lager en generell showError () -metode for å vise en varslingsboks til brukeren hvis dette skjer:

 Lokalt funksjonsutvalgError () local alert = native.showAlert ("Feil!", "Vennligst prøv din dump igjen!", "OK") avslutte

På grunn av det faktum at Rails er enkelt gjenget av naturen og siden heroku gratis kontoer tillater deg å kjøre bare en enkelt server prosess; Når mobilappen fullfører POST-anropet for å sende data, skal vi undersøke serveren vår og be om et responsobjekt. Selv om dette kanskje ikke er den mest ideelle måten å arkivere dette, tillater det oss å kjøre denne typen app med svært minimale heroku serverressurser.

Her er vår avstemningslogikk nedenfor:

 hvis (jsonpost.success == true) then native.setActivityIndicator (true); lokale forsøk = 0 funksjonen henteThump (event) hvis 10 == forsøk da native.setActivityIndicator (false); timer.cancel (event.source) showError () annet lokalt svar =  lokal r, c, h = http.request url = "http: //"? APPNAME? ".Heroku.com / dunk / search? Dunk [DeviceID] ="? DeviceID? "& Dunk [lat] ="? latitudeText? "& Dunk [lng] ="? longitudeText, method = "GET", sink = ltn12.sink.table (respons) lokal jsonget = Json.Decode (table.concat (response, ")) hvis (jsonget.success == true) then native.setActivityIndicator ); timer.cancel (event.source) lokalt varsling = native.showAlert ("Thump!", jsonget.message, "OK") endforsøk = forsøk + 1 timer.performWithDelay (3000, retrieveThump) sluttider. performWithDelay (1000, retrieveThump) else showError () slutten

La oss slå det ned:

 hvis (jsonpost.success == true) then native.setActivityIndicator (true) ;? Ellers showError () slutten

I tilfelle at vår "jsonpost" -variabel returnerer "success = true" fra serveren, vil vi sette vår ActivityIndicator på enheten til ekte. Dette lanserer en innfødt pacifier-komponent som signalerer brukeren at appen jobber med noe. Hvis vi ikke mottok en "suksess = sann" fra serveren, vil vi ringe til vår generiske feilfunksjon og vise feilvarslingsboksen.

 lokale forsøk = 0-funksjonen henteThump (hendelse)? slutt timer.performWithDelay (1000, retrieveThump)

I dette tilfellet setter vi en forsøksvariabel utenfor funksjonsområdet til 0. Vi vil bruke dette senere til å sette en kappe på antall forespørsler vår "retrieveThump" -valgtfunksjon kan gjøre. Corona har en innebygd timerklasse som lar oss ringe en funksjon på et tidsintervall. Timer.performWithDelay-funksjonen tar flere millisekunder og en funksjon som parametere.

 hvis 10 == forsøk da native.setActivityIndicator (false); timer.cancel (event.source) showError ()

Først vil vi sjekke om vi har utført denne funksjonen 10 ganger. Hvis dette er tilfelle, skal vi stoppe vår ActivityIndicator ved å sette den til falsk, avbryte vår timerfunksjon, og ring vår feilfunksjon for å fortelle brukeren noe gikk galt.

 ellers lokal respons =  lokal r, c, h = http.request url = "http: //"? APPNAME? ".Heroku.com / dunk / search? Dunk [DeviceID] ="? DeviceID? "& Dunk [lat] ="? latitudeText? "& Dunk [lng] ="? longitudeText, method = "GET", sink = ltn12.sink.table (respons) lokal jsonget = Json.Decode (table.concat (response, ")) hvis (jsonget.success == true) then native.setActivityIndicator ); timer.cancel (event.source) local alert = native.showAlert ("Thump!", jsonget.message, "OK") endeforsøk = forsøk + 1 timer.performWithDelay (3000, retrieveThump) slutten

Hvis vi ennå ikke har nådd 10 forsøk, skal vi utføre en HTTP-forespørsel til serveren vår for å søke etter vår matchede "thump". Funksjonen ligner POST-samtalen vi laget tidligere, bare vi passerer metoden GET i dette tilfellet fordi vi prøver å lese og ikke skrive til serveren.

Hvis du husker fra del II, opprettet vi en søkehandling i vår Railserver som søker i vår database for en matchende dump basert på våre GPS koordinater og lignende tidsstempel. Vi sender denne informasjonen til serveren via spørringsstrengen i nettadressen. I likhet med POST-samtalen, analyserer vi retur fra server som et JSON-objekt og lagrer det i en lokal luabellvariabel kalt "jsonget". Hvis vi mottar en suksess = true tilbake fra serveren, skal vi stoppe vår ActivityIndicator, stoppe utførelsen av timeren og vise meldingen vår i en advarselboks. Hvis denne prosessen mislykkes, vil vi ganske enkelt avstemme serveren på samme måte for maksimalt 10 forsøk.

Og der har du det! Denne opplæringen bør gi deg en god base for å lage forskjellige typer apper som deler data via bevegelser. Noen interessante tillegg kan være å dele via en samtidig skjermknapp, eller for å utvide programmet til å bytte bilder, enten tatt fra kameraet eller enhetens lokale fotobibliotek. Gratulerer!