Expo Apps van ExpoKit loskoppelen

In mijn Easy Native Development met Expo-post, hoorde je hoe Expo het gemakkelijker maakt voor beginners om apps te maken met React Native. Je hebt ook geleerd dat Expo ontwikkelaars toestaat om met het ontwikkelen van React Native-apps sneller aan de slag te gaan omdat Android Studio, Xcode of andere ontwikkeltools niet meer hoeven te worden opgezet.

Maar zoals je ook hebt gezien, ondersteunt Expo niet alle native functies die een app nodig heeft. Hoewel het Expo-team altijd bezig is om meer native-functionaliteit te ondersteunen, is het een goed idee om te leren hoe je een bestaand Expo-project converteert naar een standaard native project, zodat je gemakkelijk kunt overstappen als de behoefte zich voordoet. 

Dus, in deze tweedelige serie, bekijken we hoe we dat moeten doen. In het eerste deel van de serie leerde je de basisbegrippen van ExpoKit. In dit bericht gaan we verder waar we zijn gebleven door de app daadwerkelijk los te koppelen aan ExpoKit en door te gaan met het coderen van de app voor het delen van locaties. 

  • Expo Apps van ExpoKit loskoppelen: concepten

    In dit bericht leert u wat ExpoKit is en hoe het wordt gebruikt voor het toevoegen van native functionaliteit aan Expo-apps. Je zult ook enkele van zijn voors en tegens leren.
    Wern Ancheta
    Reageer Native
  • Gemakkelijker reageren op inheemse ontwikkeling met Expo

    Expo is een verzameling hulpprogramma's die het eenvoudiger maken om native Native-apps te coderen. In deze zelfstudie laat ik je zien hoe je snel React Native ...
    Wern Ancheta
    Reageer Native

Ontkoppelen van ExpoKit

Om de ExpoKit te verwijderen, moet je eerst de app.json en package.json bestanden. 

In de app.json bestand, zorg ervoor dat een naam is vastgesteld. De platforms moeten de platforms zijn waar je naar wilt bouwen.

"expo": "name": "ocdmom", "platforms": ["ios", "android"],

Als u wilt bouwen voor iOS, moet u het ios keuze:

"ios": "bundleIdentifier": "com.ocd.mom",

Als u Android wilt ondersteunen, geeft u ook de volgende optie op:

"android": "package": "com.ocd.mom"

Er zijn andere opties die zijn voorgevuld door de exp opdrachtregelprogramma toen het project werd gemaakt. Maar de enige belangrijke zijn de bundleIdentifier voor iOS en pakket voor Android. Dit zijn de unieke ID's voor de app zodra ze zijn gepubliceerd in de Apple- of Play Store. Onthechten vereist deze details omdat het de native code genereert voor de app die op een apparaat moet worden uitgevoerd. U kunt meer informatie vinden over de verschillende configuratie-opties voor de app.json bestand in de Expo-documentatie.

U kunt de volledige inhoud van het bestand in de GitHub-repo bekijken.

Open vervolgens de package.json bestand en voeg de naam van het project toe:

"naam": "ocdmom"

Dit zou de naam moeten zijn die u gebruikte toen u het project maakte met exp init. Het is heel belangrijk dat ze hetzelfde zijn, omdat de naam u specificeert in de package.json wordt gebruikt bij het compileren van de app. Inconsistenties in deze naam zullen een fout veroorzaken.

Nu zijn we klaar om los te koppelen aan ExpoKit. Voer de volgende opdracht uit in de hoofdmap van de projectdirectory:

ontkoppelen

Hiermee worden de native Expo-pakketten voor Android en iOS lokaal gedownload.

U zou een uitvoer moeten zien die lijkt op het volgende als het lukt:

Als u implementeert op iOS, moet u de nieuwste versie van Xcode installeren. Op het moment van schrijven van deze tutorial is de nieuwste versie 9. Installeer CocoaPods vervolgens door te executeren sudo gem installeer cocoapods. Hiermee kunt u de native iOS-afhankelijkheden van het project installeren. Als dat is gebeurd, navigeert u naar de ios map van het project en voer uit pod installeren om alle native afhankelijkheden te installeren. 

Aangepaste native pakketten installeren

Nu we hebben verwijderd, kunnen we nu native-pakketten installeren, net als in een standaard React Native-project. 

Voor deze app hebben we de React Native Background Timer- en Pusher-pakketten nodig.

Installeer eerst het Pusher-pakket omdat het eenvoudiger is:

npm install - save pusher-js

Dit stelt ons in staat om te communiceren met de Pusher-app die u eerder hebt gemaakt.

Installeer vervolgens de React Native Background Timer. Hierdoor kunnen we periodiek code uitvoeren (zelfs wanneer de app op de achtergrond staat) op basis van een specifiek interval:

npm install - sla react-native-achtergrond-timer op

In tegenstelling tot het Pusher-pakket, vereist dit dat een native library (iOS of Android) aan de app wordt gekoppeld. Het uitvoeren van de volgende opdracht doet dat voor u:

reactieve koppeling

Als het eenmaal klaar is, zou het ook de module moeten initialiseren android / app / src / main / host / exp / exponent / MainApplication.java. Maar controleer om te controleren of het volgende in dat bestand bestaat:

import com.ocetnik.timer.BackgroundTimerPackage; // bekijk deze openbare lijst getPackages () Arrays retourneren.asList (nieuw BackgroundTimerPackage () // ook controleren); 

Als u voor iOS bouwt, opent u de Podfile binnen in de ios map en zorg ervoor dat het volgende wordt toegevoegd vóór de post_install verklaring:

pod 'react-native-background-timer',: path => '... / node_modules / react-native-background-timer'

Als dat is gebeurd, voer je uit pod installeren binnen in de ios map om de native module te installeren.

Voor Android wordt dit al automatisch gedaan wanneer u de app uitvoert met Android Studio.

Werk het Android Manifest-bestand bij

Als u voor Android bouwt, opent u het Android-manifestbestand (android / app / src / main / AndroidManifest.xml) en zorg ervoor dat de volgende machtigingen zijn toegevoegd:

   

Hiermee kunnen we toestemming vragen aan Pusher voor toegang tot internet en Expo om de huidige locatie van de gebruiker op Android-apparaten te krijgen. 

De app uitvoeren

We zijn nog niet klaar, maar het is beter om de app nu uit te voeren, zodat u al kunt zien of deze werkt of niet. Op die manier kunt u de wijzigingen ook bekijken tijdens het ontwikkelen van de app.

De eerste stap bij het uitvoeren van de app is om uit te voeren exp start vanuit de hoofdmap van het project. Hiermee wordt de ontwikkelserver gestart, zodat elke wijziging die u aanbrengt in de broncode wordt weergegeven in het app-voorbeeld.

Als u voor Android bouwt, opent u Android Studio en selecteert u Open een bestaand Android Studio-project. Selecteer de. In de indexselectie die verschijnt android map binnen het Expo-project. Nadat u de map hebt geselecteerd, moet deze de bestanden in die map indexeren. Op dat moment zou u nu in staat moeten zijn om het project opnieuw op te bouwen door te selecteren Build> Rebuild Project vanuit het topmenu. Zodra dat is gebeurd, start u de app door te selecteren Uitvoeren> Run 'app'.

Android Studio kan de app uitvoeren op elk Android-apparaat dat is aangesloten op uw computer, op een van de emulators die u hebt geïnstalleerd via Android Studio of via Genymotion (Android Studio detecteert automatisch een actieve emulatie-instantie). Voor deze app raad ik je aan de Genymotion-emulator te gebruiken, omdat deze een leuke GPS-emulatie-widget heeft waarmee je de locatie kunt wijzigen via een Google Maps-interface:

(Als u problemen ondervindt bij het uitvoeren van de app op uw apparaat, moet u deze Stack Overflow-vraag bekijken om ervoor te zorgen dat Android Studio uw apparaat herkent.)

Zodra dat is gebeurd, opent u de ios /ocdmom.xcworkspace bestand met Xcode. Zodra Xcode klaar is met het indexeren van de bestanden, zou je in staat moeten zijn om die grote afspeelknop te raken en het zal de app automatisch uitvoeren op je geselecteerde iOS-simulator.

Met Xcode kun je ook de locatie bespotten, maar alleen als je de app bouwt om in de simulator te draaien. Door een wijziging aan te brengen in de code en de ontwikkelserver de app te laten vernieuwen, wordt de locatie niet echt gewijzigd. Om de locatie te wijzigen, klikt u op het verzendpictogram en selecteert u de locatie die u wilt gebruiken:

Ga door met het coderen van de app

Nu zijn we klaar om door te gaan met het schrijven van de code voor de app. Deze keer zullen we de functionaliteit toevoegen om wat code uit te voeren terwijl de app op de achtergrond staat.

Een achtergrondtaak toevoegen

Importeer het Pusher- en Background Timer-pakket dat u eerder hebt geïnstalleerd:

importeer BackgroundTimer van 'react-native-background-timer'; import Pusher van 'pusher-js / react native';

Stel de waarde in voor de Google API-sleutel van het Google-project dat u eerder hebt gemaakt:

const GOOGLE_API_KEY = 'UW API-SLEUTEL VAN GOOGLE PROJECT';

Gebruik de API voor locaties en rechten van Expo:

const Locatie, Toestemmingen = Expo;

De API's van Expo werken platformoverschrijdend - dit is niet anders dan een standaard React Native-project waarbij je een pakket zoals React Native Permissies moet installeren om toegang te krijgen tot een permissies-API die platformonafhankelijk werkt.

Stel vervolgens het interval (in milliseconden) in dat de code voor het volgen van de huidige locatie van de gebruiker moet uitvoeren. In dit geval willen we dat het elke 30 minuten wordt uitgevoerd. Merk op dat we in de onderstaande code de waarde van de gebruiken location_status variabele om te controleren of de toestemming voor toegang tot de huidige locatie van de gebruiker al dan niet is toegekend. We zullen de waarde van deze variabele later instellen, zodra het onderdeel is aangekoppeld:

var interval_ms = 1800 * 100; // 1800 seconden = 30 minuten, maal 100 om te zetten in milliseconden var location_status = null; // of toegang tot de locatie van de gebruiker is toegestaan ​​of niet BackgroundTimer.runBackgroundTimer (() => // voer de achtergrondtaak uit als (location_status == 'granted') // als toestemming voor toegang tot de locatie wordt verleend door de gebruiker / / volgende: code toevoegen om de huidige locatie van de gebruiker te verkrijgen, interval_ms);

De huidige locatie ophalen

Haal de huidige locatie op met behulp van Expo's Location API:

Location.getCurrentPositionAsync (// de gebruikerscoördinaten inschakelenHighAccuracy: true // inschakelen ophalen van locatie met hoge nauwkeurigheid) .then ((res) => let latitude, longitude = res.coords; // extract the latitude and lengtewaarden // volgende: voeg code toe om het adres te krijgen op basis van de coördinaten);

Gebruik vervolgens de Google Maps Geocoding API om een ​​verzoek in te dienen voor het omgekeerde geocoderingseindpunt door de waarden voor lengte- en breedtegraden in te voeren. Hierdoor wordt een opgemaakt adres geretourneerd op basis van die coördinaten:

ophalen ('https://maps.googleapis.com/maps/api/geocode/json?latlng=$ latitude, $ longitude & key = $ GOOGLE_API_KEY') .then ((response) => reactie. json ()) .then ((responseJson) => laat addr = responseJson.results [0] .formatted_address; // next: stuur de locatie met Pusher) .catch ((error) => console.error (error ););

De locatie verzenden met Pusher

De volgende stap is om de locatie met behulp van Pusher te verzenden. Later gaan we de server maken die zal dienen als het authenticatie-eindpunt en tegelijkertijd de pagina weergeven die de huidige locatie van de gebruiker laat zien.

Werk de constructor bij om een ​​standaardwaarde in te stellen voor de Pusher-instantie:

constructor () / * de code voor het genereren van unieke code van eerder * / this.pusher = null; 

Wanneer het onderdeel is aangekoppeld, willen we Pusher initialiseren. U kunt nu de Pusher API-sleutel en cluster leveren vanuit de instelling van de Pusher-app die u eerder hebt gemaakt:

componentWillMount () this.pusher = nieuwe Pusher ('YOUR PUSHER APP KEY', authEndpoint: 'UW AUTH-SERVER ENDPOINT (MOET LATER WORDEN TOEGEVOEGD)', cluster: 'YOUR PUSHER CLUSTER', versleuteld: waar // of de verbinding wordt versleuteld of niet. Dit vereist https indien ingesteld op true); 

Vervolgens kunt u nu de code toevoegen voor het verzenden van de huidige locatie. In Pusher wordt dit gedaan door de op gang brengen() methode. Het eerste argument is de naam van de gebeurtenis die wordt geactiveerd en het tweede argument is een object dat de gegevens bevat die u wilt verzenden. 

Later, op de server, abonneren we ons op hetzelfde kanaal waarop we ons abonneren zodra het onderdeel is aangekoppeld. Dan binden we ons aan de client-locatie gebeurtenis, zodat elke keer dat deze ergens wordt geactiveerd, de server ook op de hoogte wordt gesteld (hoewel alleen wanneer de pagina die wordt weergegeven ook op hetzelfde kanaal is geabonneerd):

fetch (...) .then (...) .then ((responseJson) => let addr = responseJson.results [0] .formatted_address; current_location_channel.trigger ('client-location', addr: addr, lat: latitude, lng : lengtegraad);) .catch (...);

De enige keer dat we toestemming vragen om toegang te krijgen tot de huidige locatie van de gebruiker, is wanneer het onderdeel is aangekoppeld. We zullen dan het location_status op basis van de selectie van de gebruiker. De waarde kan worden "verleend" of "geweigerd". 

Vergeet niet dat de code voor het controleren van de huidige locatie van de gebruiker periodiek wordt uitgevoerd. Dit betekent dat de nieuwe waarde van de location_status variabele zal ook worden gebruikt op een later tijdstip wanneer de functie wordt uitgevoerd. Daarna willen we ons ook abonneren op het Pusher-kanaal waar de locatie-updates worden verzonden:

componentDidMount () try Permissions.askAsync (Permissions.LOCATION) .then ((status) => location_status = status;);  catch (error) console.log ('err:', error);  // subscribe to the Pusher channel current_location_channel = this.pusher.subscribe ('private-current-location-' + this.state.unique_code); 

De server maken

Nu zijn we klaar om de server te maken. Maak eerst je werkdirectory (ocdmom-server) buiten de projectdirectory van de app. Navigeer in die map en voer uit npm init. Druk gewoon op invoeren totdat het de package.json het dossier.

Installeer vervolgens de pakketten die we nodig hebben:

npm install - save express body-parser pusher

Hier is een overzicht van wat elk pakket doet:

  • uitdrukken: gebruikt voor het maken van een server. Dit is verantwoordelijk voor het bedienen van de trackingpagina en voor het beantwoorden van het auth-eindpunt.
  • body-parser: Express middleware die de hoofdtekst van het verzoek parseert en beschikbaar maakt als een JavaScript-object. 
  • pusher: gebruikt voor communicatie met de Pusher-app die u eerder hebt gemaakt.

Zodra dat is gebeurd, is uw package.json bestand zou er nu als volgt uit moeten zien:

"name": "ocdmom-server", "version": "1.0.0", "description": "", "main": "server.js", "scripts": "test": "echo \ "Fout: geen test opgegeven \" && exit 1 "," start ":" node server.js "," author ":" "," license ":" ISC "," dependencies ": " body-parser " : "^ 1.18.2", "express": "^ 4.16.2", "pusher": "^ 1.5.1"

Maak een server.js bestand en importeer de pakketten die we zojuist hebben geïnstalleerd:

var express = require ('express'); var bodyParser = require ('body-parser'); var Pusher = require ('pusher');

Configureer de server om de te gebruiken body-parser pakket en stel de openbaar map als de map met statische bestanden:

var app = express (); app.use (bodyParser.json ()); // middleware instellen om het aanvraaglichaam te parseren naar JavaScript-object app.use (bodyParser.urlencoded (extended: false)); // voor het parseren van URL-gecodeerde request body app.use (express.static ('public')); // geef de map op waar de statische bestanden zoals css, JavaScript en afbeeldingsbestanden leven

Initialiseer Pusher. De hier geleverde waarden komen uit de omgevingsvariabelen. We zullen die later toevoegen wanneer we de server inzetten:

var pusher = new Pusher (appId: process.env.APP_ID, key: process.env.APP_KEY, secret: process.env.APP_SECRET, cluster: process.env.APP_CLUSTER,);

Bedien de volgpagina wanneer de basis-URL wordt geopend:

app.get ('/', functie (req, res) res.sendFile (__ dirname + '/public/tracker.html'););

Maak vervolgens de route om te reageren op verzoeken om het authenticatie-eindpunt. Dit wordt elke keer geraakt wanneer de app de verbinding met Pusher initialiseert en ook wanneer de trackingpagina wordt geopend. Wat dit doet, is de gebruiker authenticeren, zodat deze direct vanaf de clientzijde met de Pusher-app kan communiceren. 

Merk op dat dit niet echt beveiligingsmaatregelen bevat. Dit betekent dat iedereen gewoon een verzoek kan indienen bij uw auth-eindpunt als deze toegang heeft tot uw Pusher-app-sleutel. In een productie-app wilt u meer robuuste beveiliging!

app.post ('/ pusher / auth', functie (req, res) var socketId = req.body.socket_id; var channel = req.body.channel_name; var auth = pusher.authenticate (socketId, channel); var app_key = req.body.app_key; var auth = pusher.authenticate (socketId, channel); res.send (auth););

Laat de server ten slotte luisteren naar de poort die is opgegeven in de omgevingsvariabelen. Standaard is dit poort 80, maar we stellen deze ook in als alternatieve waarde voor het geval deze niet bestaat:

var port = process.enTIEPORT || 80; app.listen (poort);

Tracking-pagina

Op de volgpagina wordt een kaart weergegeven die telkens wordt bijgewerkt client-locatie gebeurtenis wordt geactiveerd vanuit de app. Vergeet niet om uw Google API-sleutel op te geven:

     OCDMom Tracker      

Maak vervolgens een public / js / tracker.js bestand en voeg het volgende toe:

function getParameterByName (name, url) if (! url) url = window.location.href; name = name.replace (/ [\ [\]] / g, "\\ $ &"); var regex = new RegExp ("[? &]" + naam + "(= ([^ & #] *) | & | # | $)"), results = regex.exec (url); als (! resultaten) null retourneren; als (! resultaten [2]) terugkeren "; return decodeURIComponent (results [2] .replace (/ \ + / g," "));

De bovenstaande functie haalt de queryparameter uit de URL. De unieke code (die wordt weergegeven in de app) moet worden opgenomen als een queryparameter wanneer de basis-URL van de server wordt gebruikt in een browser. Dit stelt ons in staat om de locatie van de gebruiker bij te houden omdat deze ons zal inschrijven op hetzelfde kanaal als waarop de app zich heeft geabonneerd.

Start vervolgens Pusher. De code lijkt eerder op de code op de server. Het enige verschil is dat we alleen de app-sleutel van de opdringer, het authenticatie-eindpunt en de cluster moeten specificeren:

var pusher = new Pusher ('YOUR PUSHER APP KEY', authEndpoint: 'YOUR PUSHER AUTH ENDPOINT', cluster: 'YOUR PUSHER CLUSTER', versleuteld: true);

Controleer of de code wordt geleverd als een queryparameter en abonneert zich alleen op het push-kanaal als het wordt geleverd:

var channel = null; if (getParameterByName ('code') == null) alert ('Zorg ervoor dat de code wordt geleverd als een queryparameter en ververs dan de pagina.');  else channel = pusher.subscribe ('private-current-location-' + getParameterByName ('code')); 

Voeg de functie toe voor het initialiseren van de kaart. Hierdoor wordt de kaart weergegeven samen met een markering die naar de standaardlocatie verwijst die we hebben opgegeven:

var map = null; var marker = null; function initMap () var myLatLng = // stel de standaardlocatie in die wordt weergegeven op de kaart lat: -25.363, lng: 131.044; map = new google.maps.Map (document.getElementById ('map'), zoom: 16, center: myLatLng); marker = new google.maps.Marker (position: myLatLng, map: map); 

Bind met de client-locatie evenement. De callback-functie wordt elke keer uitgevoerd als de app a activeert client-locatie gebeurtenis die dezelfde unieke code heeft als de door de gebruiker als queryparameter opgegeven:

if (channel) channel.bind ('client-location', function (data) console.log ('message received:', data); var position = new google.maps.LatLng (data.lat, data.lng ); // maak een nieuw objectpositieobject voor Google maps // stel dit in als de positie voor de markering en de kaartmarkering.setPosition (positie); map.setCenter (positie);); 

Voeg vervolgens de stijlen voor de volgpagina toe (public / css / style.css):

#map height: 100%;  html, body height: 100%; marge: 0; opvulling: 0; 

De server implementeren

We zullen Nu gebruiken om de server te implementeren. Het is gratis voor open-sourceprojecten.

Installeer nu wereldwijd:

npm nu installeren

Nadat het is geïnstalleerd, kunt u de aanmeldingsgegevens van de Pusher-app nu als geheimen toevoegen. Zoals eerder vermeld, is Now gratis voor open-sourceprojecten. Dit betekent dat zodra de server is geïmplementeerd, de broncode beschikbaar is op de / _src pad. Dit is niet echt goed omdat iedereen ook de inloggegevens van je Pusher-app kan zien. Dus wat we zullen doen is ze als een geheim toevoegen, zodat ze als een omgevingsvariabele toegankelijk zijn. 

Herinner de process.env.APP_ID of process.env.APP_KEY van de servercode eerder? Die worden ingesteld als omgevingsvariabelen via geheimen. pusher_app_id is de naam die aan het geheim is toegewezen, en YOUR_PUSHER_APP_ID is de ID van je Pusher-app. Voer de volgende opdrachten uit om uw Pusher-app-inloggegevens als geheimen toe te voegen:

nu geheim toevoegen pusher_app_id YOUR_PUSHER_APP_ID nu geheim toevoegen pusher_app_key YOUR_PUSHER_APP_KEY nu geheim toevoegen pusher_app_secret YOUR_PUSHER_APP_SECRET nu geheim toevoegen pusher_app_cluster YOUR_PUSHER_APP_CLUSTER

Zodra u deze hebt toegevoegd, kunt u nu de server implementeren. APP_ID is de naam van de omgevingsvariabele, en pusher_app_id is de naam van het geheim dat u wilt openen:

nu -e APP_ID = @ pusher_app_id -e APP_KEY = @ pusher_app_key -e APP_SECRET = @ pusher_app_secret APP_CLUSTER = @ pusher_app_cluster

Zo ziet het eruit zodra het klaar is met de implementatie. De URL die wordt geretourneerd is de basis-URL van de server:

Kopieer die URL naar de App.js bestand en sla de wijzigingen op:

this.pusher = nieuwe Pusher ('UW DRUKPERSEN APP TOETS', authEndpoint: 'https: // BASE-URL-OF-YOUR-SERVER / pusher / auth', cluster: 'YOUR PUSHER APP CLUSTER', versleuteld: true );

Op dit moment zou de app nu volledig functioneel moeten zijn.

Conclusie

Dat is het! In deze tweedelige serie heb je geleerd hoe je een bestaand Expo-project kunt losmaken van ExpoKit. ExpoKit is een goede manier om een ​​aantal tools te gebruiken die het Expo-platform biedt, terwijl je app al is omgezet naar een standaard native project. Hiermee kunt u bestaande native modules voor React Native gebruiken en uw eigen modules maken. 

Terwijl je hier bent, bekijk enkele van onze andere berichten over de ontwikkeling van de React Native-app!

  • Een app coderen met GraphQL, React Native en AWS AppSync: het back-end

    In deze zelfstudies laat ik u zien hoe u een GraphQL-database kunt maken en ermee kunt werken met behulp van AWS AppSync en React Native. Deze app heeft realtime en ...
    Nader Dabit
    GraphQL
  • Aan de slag met natuurlijke indelingen van React

    In deze tutorial leer je hoe je React Native-apps kunt indelen en hoe je lay-outs kunt implementeren die vaak in apps worden gebruikt.
    Wern Ancheta
    Reageer Native
  • Tools voor React Native Development

    In dit artikel zal ik u enkele van de hulpmiddelen voorlezen die u kunnen helpen om productiever te worden bij het werken met React Native-projecten.
    Wern Ancheta
    Mobiele ontwikkeling
  • Praktische animatievoorbeelden in React Native

    In deze zelfstudie leer je hoe veelgebruikte animaties kunnen worden geïmplementeerd in een React Native-app. Volg mee en leer om animaties te coderen die ...
    Wern Ancheta
    Reageer Native