Dela data med gester Thump Matching

Välkommen till del III i Dela Data With Gestures-serien. I del II skapade vi vår mellanliggande serverprocess i Ruby on Rails. Denna serverprocess kommer att fungera som en kanal mellan två enheter som försöker kommunicera med en gest som vi kallar en "thump". När två enheter sätts ihop, kommer servern att matcha dem genom att beräkna deras närhet till varandra via GPS-koordinater och en nästan identisk tidstämpel när de öppnade kommunikationen med servern. När den här matchningen har gjorts kommer servern att utbyta meddelanden som skrivits i mobilappen och simulera enhetens kommunikation.

I del III kommer vi att distribuera vår serverapp till heroku-plattformen och sedan uppgradera vår mobilapp för att kommunicera med den.

För att starta, kommer vi att modifiera vår dumpningsbordets migrationsfil för att vara kompatibel med Postgres. Du kan hitta den här filen i katalogen "db / migrate" och den kommer att bli namngiven något som: TIMESTAMP_create_thumps.rb. Det enklaste sättet att distribuera en heroku-app är att använda sin delade databasstjänst, som råkar vara Postgres istället för MySQL. Vi kommer att ersätta följande rader:

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

med dessa nya linjer:

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

Postgres hanterar stora decimaltyper annorlunda än MySQL gör, så det här är en nödvändig förändring för att vi ska få den datapunkts precision vi behöver i våra områden för latitud och longitud.

Eftersom det här är en Rails 2.3.5 app, använder vi den äldre heroku-metoden för att installera ädelstenar genom att skapa en .gems-fil i roten till vårt Rails-projekt. De flesta av dem kommer förmodligen att användas för att använda Bundler för den här typen av uppgift, men eftersom geokit-plugin inte har uppgraderats till att vara Rails 3.0-kompatibelt måste vi göra saker med de äldre Rails 2-konventionerna.

Vi lägger helt enkelt till följande i vår .gems-fil:

 rails -v 2.3.5 pg geokit --version '= 1.5.0'

Här specificerar vi railspärren och versionen vi använder för det här projektet, liksom postgres-pärlan och version 1.5.0 av geokit-pärlan.

Nu kan vi börja vår utplacering! Låt oss börja med att skapa ett lokalt gitförvar i vårt projekt. Allt vi behöver göra är att köra följande kommando i rotkatalogen i vårt Rails-projekt:

 $ git init

Innan vi åtar oss till detta förråd behöver vi skapa vår app på heroku-plattformen. Om du inte har anmält dig för ett gratis heroku-konto än, gör det genom att helt enkelt registrera dig på https://api.heroku.com/signup. Om du inte har heroku-pärlan installerad på ditt system, kan du göra det genom att köra följande kommando:

 $ sudo pärla installera heroku

När gemgen är installerad, kör följande kommando från insidan av projektets rotkatalog:

 $ heroku skapa - stack bambu-ree-1.8.7

Här specificerar vi bambu-ree-stapeln på grund av att det här är en Rails 2 app. Om du just har skapat ett nytt konto kan det leda till att du har ditt kontoinnehav från Heroku-kontot. När du har skrivit in kommer dessa uppgifter att lagras för framtida interaktioner med heroku-servrarna. Om allt går bra ska heroku reagera med något som följande:

 Skapat http://APPNAME.heroku.com/ | [email protected]: APPNAME.git Git Remote Heroku läggs till

Här har jag ersatt det aktuella applikationsnamnet och underdomänen med en platshållare som heter APPNAME. Notera denna APPNAME som vi kommer att använda den senare. Nu ska vi begå våra projektfiler till det lokala gitförvaret som vi skapade tidigare. Det är så enkelt som att köra dessa två kommandon:

 $ git lägg till. $ git commit -m "min första commit"

När projektet är helt engagerat i lokala git repo måste vi trycka det på fjärrförvaret som skapades när vi körde kommandot Heroku Create.

 $ git push heroku master

Heroku-pärlan gör att du kan exekvera rakekommandon på servern med kommandot "heroku rake". För att slutföra implementeringen måste vi köra våra databasmigrationer som kommer att generera vårt tippabord i heroku-databasen.

 $ heroku rake db: migrera

grattis! Du har framgångsrikt distribuerat vår Thump Server-applikation till Heroku-plattformen. Nu tillbaka till mobilappen!

Låt oss öppna vår main.lua-fil i vår Corona-app och lägg till följande rader till toppen:

 http = kräver ("socket.http") ltn12 = kräver ("ltn12") url = kräver ("socket.url") kräver ("json")

Vi måste kräva några bibliotek som gör det möjligt för oss att skapa en anslutning till vår serverapp. Vi kommer också att inkludera JSON-parsing-biblioteket så att vi kan förstå de responsobjekt som servern ska skicka tillbaka.

Kom ihåg den APPNAME som gavs när vi först skapade programmet heroku? Det är dags att använda det nu:

 lokala appname = "APPNAMEHERE"

Denna variabel kommer att kombineras med andra senare för att generera vår serveradress för extern kommunikation.

I del I hade vi appen en varningsruta med vårt meddelande när det upptäckte en "thump" eller shake gest. Eftersom vi behöver kommunicera detta meddelande till servern tar vi bort följande rad från vår getThump-funktion:

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

Nu ska vi lägga till lite funktionalitet till denna getThump-metod för att skicka meddelandet till servern. Låt oss bryta ner det här:

 lokalt meddelande = textField.text local post = "thump [deviceid] ="? enhets-ID? "& Svänga [lat] =" latitudeText? "& Svänga [LNG] =" longitudeText? "& Svänga [meddelande] =" meddelande lokalt svar = 

Här genererar vi våra variabler för att skicka till servern. "Posten" -variabeln är inställd i frågesträngformatet och vårt "svar" förklaras som ett tomt tabellobjekt för nu.

 lokal r, c, h = http.request url = "http: //"? app-namn? ".heroku.com / thumps", method = "POST", rubriker = ["innehållslängd"] = #post, ["Content-Type"] = "application / x-www-form-urlencoded", source = ltn12.source.string (post), sink = ltn12.sink.table (svar) local jsonpost = Json.Decode (table.concat (response, "))

Här utför vi en HTTP-förfrågan av typen POST till vår server. Vi subbing i vår variabell för appnamn som underdomän för webbadressen. Rubrikerna är standard för ett typiskt postsamtal. I fältet "innehållslängd" uttrycker lua-syntaxen för att sätta en # framför variabeln längden i tecken på den strängen. Eftersom vi vill lagra serverns repsonse i en variabel som heter "svar", kommer vår sista rad att avkoda den variabeln som ett JSON-objekt och skapa ett lua-tabellobjekt så att vi kan komma åt fält inom det.

Vid ett kommunikationsfel måste vi varna användaren om att något har gått fel. Vi skapar en generell showError () -metod för att visa en varningsruta för användaren om det här inträffar:

 Lokal funktionsvisningError () local alert = native.showAlert ("Fel!", "Var god försök igen!", "OK") avsluta

På grund av att Rails är enkeltgängade av naturen och eftersom Heroku gratis konton tillåter dig att köra bara en enda serverprocess. När mobilappen har slutfört POST-samtalet för att skicka data, kommer vi att kolla på vår server och be om ett svarobjekt. Även om detta kanske inte är det mest idealiska sättet att arkivera detta, tillåter det oss att köra den här typen av app med mycket minimala Heroku-serverresurser.

Här är vår omröstningslogik nedan:

 om (jsonpost.success == true) sedan native.setActivityIndicator (true); lokala försök = 0 funktionen retrieveThump (händelse) om 10 == försök sedan native.setActivityIndicator (false); timer.cancel (event.source) showError () annat lokalt svar =  local r, c, h = http.request url = "http: //"? app-namn? ".Heroku.com / dunkar / search? Dunka [Enhets] =" enhets-ID? "& Svänga [lat] =" latitudeText? "& Svänga [LNG] =" longitudeText, method = "GET", sink = ltn12.sink.table (svar) local jsonget = Json.Decode (table.concat (response, ")) om (jsonget.success == true) then native.setActivityIndicator ); timer.cancel (event.source) local alert = native.showAlert ("Thump!", jsonget.message, "OK") slutförsök = försök + 1 timer.performWithDelay (3000, retrieveThump) ändtidstimer. performWithDelay (1000, retrieveThump) annars showError () slutet

Låt oss bryta ner det:

 om (jsonpost.success == true) sedan native.setActivityIndicator (true) ;? annars showError () slutet

I händelse av att vår "jsonpost" -variabel returnerar "success = true" från servern, sätter vi vår ActivityIndicator på enheten till sann. Detta startar en inbyggd nappkomponent som signalerar användaren att appen arbetar på något. Om vi ​​inte fick en "success = true" från servern, kommer vi att ringa till vår generiska felfunktion och visa felvarningsrutan.

 lokala försök = 0 funktionshämtningTillgång (händelse)? avsluta timer.performWithDelay (1000, hämtaThump)

I det här fallet ställer vi in ​​en försöksvariabel utanför vårt funktionsområde till 0. Vi använder det senare för att lägga en koll på antalet förfrågningar som vår "retrieveThump" -valfunktion kan göra. Corona har en inbyggd timer klass som gör att vi kan ringa en funktion på ett tidsintervall. Timern.performWithDelay-funktionen tar ett antal millisekunder och en funktion som parametrar.

 om 10 == försök då native.setActivityIndicator (false); timer.cancel (event.source) showError ()

Först ska vi kolla om vi har utfört denna funktion 10 gånger. Om så är fallet ska vi sluta vår ActivityIndicator genom att ställa in den till falsk, avbryta vår timerfunktion och ringa sedan vår felfunktion för att berätta för användaren att något gick fel.

 annat lokalt svar =  lokal r, c, h = http.request url = "http: //"? app-namn? ".Heroku.com / dunkar / search? Dunka [Enhets] =" enhets-ID? "& Svänga [lat] =" latitudeText? "& Svänga [LNG] =" longitudeText, method = "GET", sink = ltn12.sink.table (svar) local jsonget = Json.Decode (table.concat (response, ")) om (jsonget.success == true) then native.setActivityIndicator ); timer.cancel (event.source) local alert = native.showAlert ("Thump!", jsonget.message, "OK") slutförsök = försök + 1 timer.performWithDelay (3000, retrieveThump) slut

Om vi ​​inte har nått 10 försök än, kommer vi att utföra en HTTP-begäran till vår server för att söka efter vår matchade "thump". Funktionen liknar POST-samtalet som vi gjorde tidigare bara vi passerar metoden GET i det här fallet eftersom vi försöker läsa och inte skriva till servern.

Om du kommer ihåg från del II skapade vi en sökåtgärd på vår Railserver som söker vår databas för en matchande dump baserat på våra GPS-koordinater och liknande tidsstämpel. Vi skickar denna information till servern via frågesträngen i webbadressen. På samma sätt som POST-samtalet analyserar vi returen från servern som ett JSON-objekt och lagrar det i en lokal luabellvariabel som heter "jsonget". Om vi ​​får en succé = sant tillbaka från servern ska vi sluta vår ActivityIndicator, stoppa vår körning av timern och visa vårt meddelande i en varningsruta. Om denna process misslyckas, kommer vi helt enkelt att undersöka servern igen på samma sätt för högst 10 försök.

Och där har du det! Denna handledning ska ge dig en bra bas för att skapa olika typer av appar som delar data via gester. Några intressanta tillägg kan vara att dela via en samtidig skärmknapp eller för att utöka programmet för att byta bilder antingen från kameran eller enhetens lokala fotobibliotek. Grattis!