În versiunea mai ușoară de reacție a dezvoltării native cu postul Expo, ați aflat despre modul în care Expo îi ușurează pe începători să creeze aplicații cu React Native. Ați învățat, de asemenea, că Expo permite dezvoltatorilor să se dezvolte mai repede, deoarece nu mai este nevoie să configurați aplicații Android Studio, Xcode sau alte instrumente de dezvoltare.
Dar, așa cum ați văzut, Expo nu suportă toate caracteristicile native pe care o aplicație le-ar putea avea nevoie. Deși echipa Expo lucrează întotdeauna pentru a susține funcționalitatea mai nativă, este o idee bună să învățați cum să convertiți un proiect Expo existent într-un proiect nativ standard, astfel încât să puteți trece cu ușurință în caz de necesitate.
Deci, în această serie de două părți, ne uităm cum să facem asta. În prima parte a seriei, ați învățat conceptele de bază ale ExpoKit. În această postare, vom continua acolo unde am rămas, detașând aplicația de ExpoKit și continuând să codificăm aplicația de distribuire a locației.
Pentru a vă detașa la ExpoKit, trebuie mai întâi să editați app.json și package.json fișiere.
În app.json fișier, asigurați-vă că a Nume
a fost stabilit. platforme
ar trebui să fie platformele pe care doriți să le construiți.
"expo": "nume": "ocdmom", "platforme": ["ios", "android"],
Dacă doriți să construiți pentru iOS, trebuie să specificați ios
opțiune:
"ios": "bundleIdentifier": "com.ocd.mom",
Dacă doriți să acceptați Android, specificați și următoarea opțiune:
"android": "pachet": "com.ocd.mom"
Există și alte opțiuni care au fost preîncărcate de către exp
instrument de linie de comandă atunci când proiectul a fost creat. Dar cele mai importante sunt cele bundleIdentifier
pentru iOS și pachet
pentru Android. Acestea vor fi ID-urile unice pentru aplicație odată ce vor fi publicate în magazinul Apple sau Play. Detașarea necesită aceste detalii, deoarece generează, de fapt, codul nativ pentru aplicația care trebuie rulată pe un dispozitiv. Puteți găsi mai multe informații despre diferite opțiuni de configurare pentru app.json fișier în documentația Expo.
Puteți vizualiza întregul conținut al fișierului în repo GitHub.
Apoi, deschideți package.json fișier și adăugați numele proiectului:
"nume": "ocdmom"
Acesta ar trebui să fie numele pe care l-ați utilizat când ați creat proiectul folosind exp init
. Este foarte important ca ele să fie aceleași pentru că Nume
pe care îl specificați în package.json se utilizează la compilarea aplicației. Neconcordanțele din acest nume vor provoca o eroare.
Acum suntem gata să ne detașăm la ExpoKit. Executați următoarea comandă la rădăcina directorului de proiect:
exp detașați
Aceasta va descărca pachetele native Expo pentru Android și iOS la nivel local.
Ar trebui să vedeți o ieșire similară cu următoarea, dacă a reușit:
Dacă desfășurați aplicații iOS, trebuie să instalați cea mai recentă versiune de Xcode. La momentul redactării acestui tutorial, ultima versiune este 9. Apoi, instalați CocoaPods executând sudo gem instala cocoapods
. Aceasta vă permite să instalați dependențele iOS native ale proiectului. Odată ce ați terminat, navigați la ios directorul proiectului și executați pod instalare
pentru a instala toate dependențele native.
Acum, că am detașat, acum putem instala pachete native ca într-un proiect React Nativ standard.
Pentru această aplicație, vom avea nevoie de pachetele React Native Timer Background și Pusher.
Mai întâi, instalați pachetul Pusher deoarece este mai ușor:
npm instalează -save pusher-js
Acest lucru ne permite să comunicăm cu aplicația Pusher pe care ați creat-o mai devreme.
Apoi, instalați cronometrul React Native Background. Acest lucru ne permite să executăm periodic codul (chiar și atunci când aplicația se află în fundal) pe baza unui anumit interval:
npm install --save reactiv-nativ-background-timer
Spre deosebire de pachetul Pusher, acest lucru necesită conectarea unei biblioteci native (fie iOS sau Android) cu aplicația. Executarea următoarei comenzi face asta pentru dvs.:
reacție-link nativ
După ce sa terminat, ar trebui să inițializați modulul Android / app / src / main / gazdă / exp / exponent / MainApplication.java. Dar doar pentru a vă asigura că verificați dacă în fișierul respectiv există următoarele:
import com.ocetnik.timer.BackgroundTimerPackage; // verificați această listă publicăgetPackages () retur Arrays. asList (noul BackgroundTimerPackage () // verificați și acest lucru);
Dacă construiți pentru iOS, deschideți Podfile în interiorul ios director și asigurați-vă că următoarele sunt adăugate înainte de post_install
declaraţie:
pod "reactiv-nativ-fundal-temporizator",: path => '... / node_modules / react-native-background-
Odată ce sa terminat, executați pod instalare
în interiorul ios
pentru a instala modulul nativ.
Pentru Android, acest lucru se face deja automat când rulați aplicația utilizând Android Studio.
Dacă construiți pentru Android, deschideți fișierul manifest Android (Android / app / src / main / AndroidManifest.xml) și asigurați-vă că sunt adăugate următoarele permisiuni:
Acest lucru ne permite să solicităm permisiunea Pusher de a accesa internetul și Expo pentru a obține locația curentă a utilizatorului pe dispozitivele Android.
Nu am terminat încă, dar este mai bine să rulați aplicația acum, astfel încât să puteți vedea deja dacă funcționează sau nu. Astfel, puteți vedea și modificările în timp ce dezvoltăm aplicația.
Primul pas în rularea aplicației este de a executa începeți
din directorul rădăcină al proiectului. Acest lucru va porni serverul de dezvoltare astfel încât orice modificare făcută de codul sursă să se reflecte în previzualizarea aplicației.
Dacă construiți pentru Android, deschideți Android Studio și selectați Deschideți un proiect Android Studio existent. În selectorul de directoare care apare, selectați Android folder în cadrul proiectului Expo. După ce ați selectat dosarul, acesta ar trebui să indexeze fișierele din acel director. În acest moment, acum ar trebui să puteți reconstrui proiectul selectând Build> Rebuild Project din meniul de sus. După ce sa terminat, rulați aplicația selectând Run> Run 'app'.
Android Studio poate rula aplicația pe orice dispozitiv Android conectat la computer, pe unul dintre emulatorii pe care l-ați instalat prin Android Studio sau prin Genymotion (aplicația Android Studio detectează automat o instanță emulator care rulează). Pentru această aplicație, vă recomandăm să utilizați emulatorul Genymotion, deoarece are un widget frumos de emulare GPS care vă permite să schimbați locația printr-o interfață Hărți Google:
(Dacă întâmpinați probleme la rularea aplicației de pe dispozitiv, asigurați-vă că ați verificat această întrebare privind depășirea stack-ului pentru a obține recunoașterea de către dispozitivul Android a dispozitivului dvs.)
Odată ce sa terminat, deschideți-l ios /ocdmom.xcworkspace fișier cu Xcode. Odată ce Xcode se face indexarea fișierelor, ar trebui să puteți atinge acel buton mare de redare și acesta va rula automat aplicația pe simulatorul dvs. iOS selectat.
Xcode vă permite, de asemenea, să mângâieți locația, dar numai atunci când construiți aplicația pentru a rula în simulator. Efectuarea unei modificări a codului și actualizarea serverului de dezvoltare a aplicației nu va schimba locația. Pentru a schimba locația, faceți clic pe pictograma de trimitere și selectați locația pe care doriți să o utilizați:
Acum suntem gata să continuăm să scriem codul pentru aplicație. De data aceasta, vom adăuga funcționalitatea pentru a rula un anumit cod în timp ce aplicația se află în fundal.
Importați pachetul Pusher și cronometrul de fundal pe care l-ați instalat mai devreme:
import BackgroundTimer din "reactiv-nativ-background-timer"; import Pusher de la "pusher-js / reaction-native";
Setați valoarea pentru cheia API Google a proiectului Google pe care l-ați creat mai devreme:
const GOOGLE_API_KEY = 'PROIECTUL APIULUI GOOGLE API';
Utilizați API-ul pentru locație și permisiuni din Expo:
const Locație, Permisiuni = Expo;
API-urile Expo funcționează pe mai multe platforme - acest lucru nu este diferit de un proiect React Nativ standard în care trebuie să instalați un pachet ca Reactive Native Permissions pentru a obține acces la un permis API care funcționează pe mai multe platforme.
Apoi, setați intervalul (în milisecunde) că codul de urmărire a locației curente a utilizatorului va fi executat. În acest caz, vrem să se execute la fiecare 30 de minute. Rețineți că în codul de mai jos utilizați valoarea location_status
pentru a verifica dacă permisiunea de a accesa locația curentă a utilizatorului a fost acordată sau nu. Vom stabili valoarea acestei variabile mai târziu, odată ce componenta va fi montată:
var interval_ms = 1800 * 100; // 1800 secunde = 30 de minute, ori 100 pentru a converti la milisecunde var loc_status = null; // dacă accesul la locația utilizatorului este permis sau nu BackgroundTimer.runBackgroundTimer (() => // executați sarcina de fundal dacă location_status == 'acordat') // dacă permisiunea de a accesa locația este acordată de utilizator / / next: adăugați codul pentru obținerea locației curente a utilizatorului, interval_ms);
Obțineți locația curentă utilizând API pentru locația Expo:
Loc.getCurrentPositionAsync (// obține coordonatele utilizatorului enableHighAccuracy: true // permite preluarea locației de înaltă precizie) .then ((res) => let latitude, longitude = res.coords; // extrage latitudinea și longitudine valori // următor: adăugați codul pentru obținerea adresei pe baza coordonatelor);
Apoi, folosind API-ul Geocoding Google Maps, faceți o solicitare la punctul final de geocodificare inversă furnizând valorile latitudinii și longitudinii. Aceasta returnează o adresă formatată pe baza acelor coordonate:
preluați ("https://maps.googleapis.com/maps/api/geocode/json?latlng=$ latitude, $ longitude & key = $ GOOGLE_API_KEY") .then ((răspunsul) => răspuns. (error) => console.error (error error) ););
Următorul pas este să trimiteți locația folosind Push. Mai târziu, vom crea serverul care va servi ca punct de final auth și va afișa în același timp pagina care arată locația curentă a utilizatorului.
Actualizați constructorul pentru a seta o valoare implicită pentru instanța Pusher:
constructor () / * codul pentru generarea unui cod unic de la * / this.pusher = null;
Când componenta este montată, vrem să inițializăm Pusher. Acum puteți furniza cheia și cluster-ul API Pusher din setarea aplicației Pusher pe care ați creat-o mai devreme:
componentul WillMount () this.pusher = nou Pusher ('PUHER APP KEY', authEndpoint: 'AUTO SERVER ENDPOINT (AU ADĂUIT ULTER)', cluster: 'PUSHER CLUSTER' va fi criptat sau nu. Aceasta necesită https dacă este setat la true);
Apoi, acum puteți adăuga codul pentru trimiterea locației curente. În Pusher, acest lucru se face prin apelarea declanșare ()
metodă. Primul argument este numele evenimentului care este declanșat, iar al doilea argument este un obiect care conține datele pe care doriți să le trimiteți.
Mai târziu, pe server, ne vom abona la același canal la care ne vom abona la montarea componentei. Apoi ne vom lega de client-locație
astfel încât de fiecare dată când este declanșat de undeva, serverul va fi, de asemenea, notificat (deși numai atunci când pagina pe care o deservește este, de asemenea, abonată la același canal):
fetch (...) .then (...) .then ((răspunsJson) => lăsa addr = replyJson.results [0] .formatted_address; current_location_channel.trigger ('client-location', addr: : longitudine);) .catch (...);
Singura dată când vom cere permisiunea de a accesa locația curentă a utilizatorului este momentul în care componenta este montată. Vom actualiza apoi location_status
pe baza selecției utilizatorului. Valoarea poate fi "acordată" sau "refuzată".
Rețineți că codul pentru verificarea locației curente a utilizatorului este executat periodic. Aceasta înseamnă că noua valoare a location_status
variabila va fi de asemenea folosita la un moment ulterior cand functia este executata. După aceasta, dorim să ne abonați la canalul Pusher unde vor fi trimise actualizările de locație:
componentDidMount () try Permissions.askAsync (Permissions.LOCATION) .then ( => location_status = status;); captură (eroare) console.log ('err:', eroare); // abonați la canalul Pusher current_location_channel = this.pusher.subscribe ('private-current-location-' + this.state.unique_code);
Acum suntem gata să creăm serverul. Mai întâi, creați directorul de lucru (ocdmom-Server) în afara directorului de proiect al aplicației. Navigați în interiorul directorului și executați npm init
. Doar apăsați introduce până când creează package.json fişier.
Apoi, instalați pachetele de care avem nevoie:
npm instalează -save exprima corpul parserului
Iată o prezentare generală a ceea ce face fiecare pachet:
expres
: utilizat pentru crearea unui server. Acesta este responsabil pentru difuzarea paginii de urmărire, precum și pentru răspunsul la punctul final al autorului.corp-parser
: Express middleware care analizează corpul solicitării și îl face disponibil ca obiect JavaScript. împingător
: utilizat pentru comunicarea cu aplicația Pusher creată anterior.Odată ce sa terminat, tu package.json fișierul ar trebui să arate astfel:
"nume": "ocdmom-server", "versiune": "1.0.0", "descriere" "Eroare: nici un test specificat \" && ieșire 1 "," start ":" nod server.js "," autor ":" ", : "^ 1.18.2", "expres": "^ 4.16.2", "împingător": "^ 1.5.1"
Creeaza o server.js fișierul și importul pachetelor pe care tocmai le-am instalat:
var express = necesită ("expres"); var bodyParser = necesită ('body-parser'); var Pusher = necesită ("împingător");
Configurați serverul să utilizeze corp-parser
pachet și setați public dosar în directorul de fișiere statice:
var app = expres (); app.use (bodyParser.json ()); // setați middleware pentru a analiza corpul cererii pentru obiectul JavaScript app.use (bodyParser.urlencoded (extended: false)); // pentru parsarea adresei URL a solicitării codului de cerere al aplicației (express.static ('public')); // specificați directorul în care se află fișierele statice cum ar fi css, JavaScript și fișierele imagine
Inițializați cursorul. Valorile furnizate aici vor proveni din variabilele de mediu. Vom adăuga mai târziu, când implementăm serverul:
var pusher = Pusher nou (appId: process.env.APP_ID, cheie: process.env.APP_KEY, secret: process.env.APP_SECRET, cluster: process.env.APP_CLUSTER,);
Utilizați pagina de urmărire atunci când adresa URL de bază este accesată:
app.get ('/', funcția (req, res) res.sendFile (__ dirname + '/public/tracker.html'););
Apoi, creați ruta pentru a răspunde solicitărilor la punctul final al auth. Acest lucru va fi lovit de fiecare dată când aplicația inițializează conexiunea la Pusher, precum și când este accesată pagina de urmărire. Ceea ce face acest lucru este autentificarea utilizatorului, astfel încât să poată comunica aplicației Pusher direct din partea clientului.
Rețineți că acest lucru nu are în realitate niciun fel de măsuri de securitate. Aceasta înseamnă că oricine poate face o cerere către punctul final al auth, dacă are acces la cheia App Pusher. Într-o aplicație de producție, doriți o securitate mai robustă!
app.post ('/ pusher / auth', funcția (req, res) var socketId = req.body.socket_id; var canal = req.body.channel_name; var auth = pusher.authenticate (socketId, canal); = req.body.app_key; var auth = pusher.authenticate (socketId, canal); res.send (auth););
În cele din urmă, faceți serverul să asculte portul specificat în variabilele de mediu. În mod implicit, este portul 80, dar îl setăm și ca o valoare alternativă doar în cazul în care nu există:
var port = process.env.PORT || 80; app.listen (port);
Pagina de urmărire afișează o hartă care se actualizează de fiecare dată client-locație
evenimentul este declanșat din aplicație. Nu uitați să furnizați cheia dvs. API Google:
OCDMom Tracker
Apoi, creați un / publice / js tracker.js fișier și adăugați următoarele:
funcția getParameterByName (nume, url) if (! url) url = window.location.href; nume = nume.replace (/ [\ [\]] / g, "\\ $ &"); var regex = noua RegExp ("[? &]" + nume + "(= ([^ & #] *) | & | # | $)"), results = regex.exec (url); dacă (! results) returnați null; dacă return [2]) returnează "; return decodeURIComponent (results [2] .replace (/ \ + / g," "))
Funcția de mai sus extrage parametrul de interogare de la adresa URL. Codul unic (cel afișat în aplicație) trebuie să fie inclus ca parametru de interogare când adresa URL de bază a serverului este accesată într-un browser. Acest lucru ne permite să urmărim locația utilizatorului, deoarece ne va abona la același canal ca cel la care sa abonat aplicația.
Apoi, inițializați Pusher. Codul este similar cu cel din serverul anterior. Singura diferență este că trebuie doar să specificăm cheia aplicației Pusher, punctul final și cluster-ul:
var pusher = Pusher nou ("PUHER APP KEY", authEndpoint: 'PUSHER AUTO ENDPOINT', cluster: 'PUSHER CLUSTER', criptat: true);
Verificați dacă cod
este furnizat ca parametru de interogare și se abonează numai la canalul Pusher dacă este furnizat:
var canal = null; if (getParameterByName ('code') == null) alert ('Asigurați-vă că codul este furnizat ca parametru de interogare, apoi actualizați pagina.'); altceva channel = pusher.subscribe ('private-current-location-' + getParameterByName ('cod'));
Adăugați funcția pentru inițializarea hărții. Aceasta va afișa harta împreună cu un marcator indicând locația prestabilită pe care am specificat-o:
var hartă = null; var marker = null; funcția initMap () var myLatLng = // setați locația implicită afișată pe hartă lat: -25.363, lng: 131.044; map = nou google.maps.Map (document.getElementById ('map'), zoom: 16, center: myLatLng); marker = nou google.maps.Marker (position: myLatLng, map: map);
Obligați-vă la client-locație
eveniment. Funcția de apel invers devine executată de fiecare dată când aplicația declanșează a client-locație
eveniment care are același cod unic ca cel furnizat de utilizator ca parametru de interogare:
dacă (canal) channel.bind ("locația clientului", funcția (data) console.log ('mesajul primit:', data); var position = new google.maps.LatLng (data.lat, data.lng ); // a crea un nou obiect de poziție Google maps // setați-l ca poziție pentru marker și marker.setPosition (poziție); map.setCenter (position););
Apoi, adăugați stilurile pentru pagina de urmărire (publice / css / style.css):
#map height: 100%; html, corp înălțime: 100%; marja: 0; umplutura: 0;
Vom folosi Now pentru a implementa serverul. Este gratuit pentru proiecte cu surse deschise.
Instalați acum la nivel global:
npm instala acum
După ce este instalat, puteți adăuga acum acreditările aplicației Pusher ca fiind secrete. Așa cum am menționat mai devreme, acum este gratuit pentru proiecte cu sursă deschisă. Aceasta înseamnă că odată ce serverul a fost implementat, codul sursă va fi disponibil la / _src
cale. Acest lucru nu este cu adevărat bun, deoarece toată lumea vă poate vedea și acreditările aplicației Pusher. Deci, ceea ce vom face este să le adăugăm ca un secret, astfel încât să poată fi accesate ca variabilă de mediu.
Amintiți-vă process.env.APP_ID
sau process.env.APP_KEY
de la codul serverului mai devreme? Acestea sunt stabilite ca variabile de mediu prin secrete. pusher_app_id
este numele atribuit secretului și YOUR_PUSHER_APP_ID
este ID-ul aplicației dvs. Pusher. Executați următoarele comenzi pentru a adăuga acreditările aplicației Pusher drept secrete:
acum secret adăugați pusher_app_id YOUR_PUSHER_APP_ID acum secret adăugați pusher_app_key YOUR_PUSHER_APP_KEY acum secret adăugați pusher_app_secret YOUR_PUSHER_APP_SECRET acum secret adăuga pusher_app_cluster YOUR_PUSHER_APP_CLUSTER
După ce le-ați adăugat, puteți instala acum serverul. APP_ID
este numele variabilei de mediu și pusher_app_id
este numele secretului pe care doriți să-l accesați:
acum -e APP_ID = @ pusher_app_id -e APP_KEY = @ pusher_app_key -e APP_SECRET = @ pusher_app_secret APP_CLUSTER = @ pusher_app_cluster
Acesta este modul în care arată după ce sa terminat implementarea. Adresa URL pe care o returnează este adresa URL de bază a serverului:
Copiați adresa URL la App.js fișier și salvați modificările:
this.pusher = Pusher nou ("PUNCTUL APĂ PUSHER", authEndpoint: 'https: // BASE-URL-OF-SERVER-pusher / auth', cluster: 'APP PUSHER APP CLUSTER' );
În acest moment, aplicația ar trebui să fie pe deplin funcțională.
Asta e! În această serie din două părți, ați învățat cum să detașați un Expo existent la ExpoKit. ExpoKit este o modalitate bună de a utiliza unele dintre instrumentele pe care le oferă platforma Expo în timp ce aplicația dvs. este deja convertită într-un proiect nativ standard. Acest lucru vă permite să utilizați modulele native existente pentru React Native și să vă creați propriile.
În timp ce sunteți aici, consultați câteva dintre celelalte postări despre dezvoltarea aplicațiilor Reactive Native!