Spostarsi oltre i principi fondamentali: Perché in tempo reale Location Matters

Quando fatto a destra, trasforma un'app statica in uno strumento di conoscenza del contesto che anticipa ciò che gli utenti hanno bisogno. React Native Maps combinato con l'API Geolocation è l'approccio standard del settore per questo, e si integrano naturalmente con un CMS senza testa come Directus.

Panoramica sull'architettura: Dove Directus si adatta

React Native gestisce il frontend mobile, inclusi i dati di visualizzazione della mappa e di localizzazione grezzo. Directus agisce come backend e headless CMS. Memorizza le storie di localizzazione degli utenti, le definizioni di geofence e qualsiasi metadati di cui hai bisogno.

Per un'analisi più approfondita delle capacità di modellazione dei dati di Directus, vedere la Guida Directus Data Modeling[.

Prerequisiti e Setup dei pacchetti

Per lo sviluppo locale, è possibile eseguire Directus tramite Docker. Ecco i pacchetti principali di cui hai bisogno nel tuo progetto React Native:

  • react-native-maps[] – Fornisce il componente della mappa e sovrapposizione del marcatore.
  • @react-native-community/geolocation[[] – Accesso al GPS dispositivo e alla posizione di rete.
  • @react-native-community/geolocation[[] – Accesso al GPS dispositivo e alla posizione di rete.

Installarli dalla radice del progetto:

npm install react-native-maps @react-native-community/geolocation

Per iOS, eseguire per collegare i moduli nativi. Se si utilizza Expo, è necessario espellere il flusso di lavoro nudo o utilizzare il [ perché queste librerie richiedono il collegamento del modulo nativo. Dopo l'installazione, verificare tutto compilando l'applicazione su un simulatore o dispositivo prima di passare.

Permessi della piattaforma: Il portiere

Sia Android che iOS richiedono un esplicito consenso dell'utente per accedere alla posizione. Non gestire le autorizzazioni con grazia è la causa numero uno dei crash runtime e delle recensioni negative.

Configurazione Android

Apri e aggiungi queste autorizzazioni all'interno del blocco , prima dell'elemento :

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

dà l'accuratezza del GPS, mentre [] fornisce un fallback utilizzando Wi-Fi e torri cellulari. Compreso entrambi permette la vostra applicazione degrada con grazia in ambienti dove il GPS è debole, come al chiuso.

Configurazione iOS

Apri e aggiungi una o entrambe queste chiavi:

<key>NSLocationWhenInUseUsageDescription</key>
<string>This app needs your location to show nearby services and track your route.</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>This app needs background location access to provide continuous route tracking.</string>

Evita stringhe generiche come “ la tua app ha bisogno di accedere alla tua posizione,” come i recensori possono rifiutarla. Sii specifico: “Per mostrare i caffè nelle vicinanze e fornire la navigazione gira per volta, ”] per esempio. Inizia con solo se si Aggiorna il tracciamento chiave è sempre necessario.

Gestione delle autorizzazioni di runtime in React Native

È inoltre necessario richiedere il permesso a runtime, in particolare su Android 6.0+ e iOS 8.0+. Utilizzare il modulo [] per Android e fare affidamento sulla libreria di geolocalizzazione nativa per iOS, che attiva automaticamente il prompt del sistema quando si chiama ] o ]].

Ecco un gancio di permesso riutilizzabile:

import { PermissionsAndroid, Platform } from 'react-native';

const requestLocationPermission = async () => {
 if (Platform.OS === 'android') {
 const apiLevel = Platform.Version;
 if (apiLevel < 23) {
 // permissions granted automatically at install time
 return true;
 }
 const granted = await PermissionsAndroid.request(
 PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
 {
 title: 'Location Permission',
 message: 'This app needs access to your location.',
 buttonPositive: 'Grant',
 buttonNegative: 'Deny',
 }
 );
 return granted === PermissionsAndroid.RESULTS.GRANTED;
 }
 // iOS handles runtime permission via the Geolocation call itself
 return true;
};

Se l'utente nega, visualizzare un messaggio amichevole che spiega l'impatto e offrire un pulsante per aprire le impostazioni del sistema. Mai semplicemente crash o visualizzare una mappa vuota.

Attuazione core: Visualizzazione dell'utente su una mappa

Con le autorizzazioni cablate, è possibile costruire il componente principale di tracciamento. Il seguente codice richiede la posizione corrente dell'utente, imposta la regione della mappa e scende un marcatore.

import React, { useState, useEffect, useRef } from 'react';
import { View, StyleSheet } from 'react-native';
import MapView, { Marker, PROVIDER_GOOGLE } from 'react-native-maps';
import Geolocation from '@react-native-community/geolocation';
import { requestLocationPermission } from './permission';

const LocationTracker = () => {
 const [region, setRegion] = useState(null);
 const [currentLocation, setCurrentLocation] = useState(null);
 const watchId = useRef(null);
 const mapRef = useRef(null);

 useEffect(() => {
 const initTracking = async () => {
 const hasPermission = await requestLocationPermission();
 if (!hasPermission) return;

 // Get the initial position immediately
 Geolocation.getCurrentPosition(
 (position) => {
 const { latitude, longitude } = position.coords;
 const initialRegion = {
 latitude,
 longitude,
 latitudeDelta: 0.01,
 longitudeDelta: 0.01,
 };
 setRegion(initialRegion);
 setCurrentLocation({ latitude, longitude });
 },
 (error) => {
 console.warn('Initial position error:', error.message);
 },
 { enableHighAccuracy: true, timeout: 15000, maximumAge: 10000 }
 );

 // Subscribe to continuous updates
 watchId.current = Geolocation.watchPosition(
 (position) => {
 const { latitude, longitude } = position.coords;
 setCurrentLocation({ latitude, longitude });
 // Optionally animate the map to follow the user
 mapRef.current?.animateToRegion({
 latitude,
 longitude,
 latitudeDelta: 0.01,
 longitudeDelta: 0.01,
 }, 500);
 },
 (error) => {
 console.warn('Watch position error:', error.message);
 },
 { enableHighAccuracy: true, distanceFilter: 10, interval: 5000 }
 );
 };

 initTracking();

 return () => {
 if (watchId.current !== null) {
 Geolocation.clearWatch(watchId.current);
 }
 };
 }, []);

 if (!region) {
 return ;
 }

 return (
 
 
 {currentLocation && (
 
 )}
 
 
 );
};

const styles = StyleSheet.create({
 container: { flex: 1 },
 map: { flex: 1 },
});

export default LocationTracker;

I principali dettagli in questa implementazione:

  • distanzaFilter: 10[] – Solo attiva un aggiornamento della posizione quando il dispositivo si muove almeno 10 metri.
  • interval: 5000[] – Caps la frequenza di aggiornamento una volta ogni 5 secondi su Android. iOS ignora questo ma utilizza il proprio frumento.
  • mostrasUserLocation[[]] – Una funzione integrata React Native Maps che visualizza un punto di sistema nativo per la posizione dell'utente, anche senza un marcatore esplicito.

Dati di localizzazione persistenti a Directus

L'esposizione della posizione su una mappa è utile, ma il valore reale deriva dalla memorizzazione e dalla querying di quei dati. In Directus, creare una raccolta chiamata locations] con questi campi:

  • id] (auto-incremento, chiave primaria)
  • user id] (stringa o relazione con directus users)
  • latitudine] (float)
  • longitudine] (float)
  • accuratezza] (float, metri)
  • timestamp[] (data, auto-generato)

Poi, all'interno del vostro callback, inviare ogni aggiornamento a Directus:

import axios from 'axios';

const DIRECTUS_URL = 'https://your-directus-instance.com';
const DIRECTUS_TOKEN = 'your-static-token-or-dynamic-jwt';

const saveLocationToDirectus = async (coords) => {
 try {
 await axios.post(
 `${DIRECTUS_URL}/items/locations`,
 {
 latitude: coords.latitude,
 longitude: coords.longitude,
 accuracy: coords.accuracy,
 // user_id is typically pulled from auth context
 },
 {
 headers: {
 Authorization: `Bearer ${DIRECTUS_TOKEN}`,
 },
 }
 );
 } catch (error) {
 console.error('Failed to save location:', error.response?.data || error.message);
 }
};

Aggiornamenti batch se si prevede di scrivere ad alta frequenza. Directus supporta la creazione di più elementi in una sola volta passando un array allo stesso endpoint.

Geofencing con React Native and Directus

Geofencing è la capacità di rilevare quando un utente entra o esce da un confine geografico predefinito. Directus può memorizzare queste definizioni di confine, e la tua app React Native può controllarle contro la posizione corrente. Questo modello alimenta le notifiche come “Benvenuto al negozio!” or “ Hai lasciato la tua area ufficio.”

Stoccaggio di Geofences in Directus

Creare una collezione chiamata geofences[]] con i seguenti campi:

  • id] (chiave principale)
  • name[] (string)
  • latitudine] (float)
  • longitudine] (float)
  • radius] (float, metri)
  • trigger on entry[] (booleano)
  • trigger on exit[ (booleano)
  • messaggio] (testo)

Controllo della geofenza client-side

Su ogni aggiornamento della posizione, prendere le geofences attive da Directus e testare la distanza tra la posizione attuale e ogni centro di recinzione. È possibile utilizzare la formula Haversine o una approssimazione più semplice:

const getDistanceFromLatLonInMeters = (lat1, lon1, lat2, lon2) => {
 const R = 6371000; // Earth's radius in meters
 const dLat = (lat2 - lat1) * Math.PI / 180;
 const dLon = (lon2 - lon1) * Math.PI / 180;
 const a =
 Math.sin(dLat / 2) * Math.sin(dLat / 2) +
 Math.cos(lat1 * Math.PI / 180) *
 Math.cos(lat2 * Math.PI / 180) *
 Math.sin(dLon / 2) *
 Math.sin(dLon / 2);
 const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
 return R * c;
};

const checkGeofences = async (currentCoords, geofences) => {
 for (const fence of geofences) {
 const distance = getDistanceFromLatLonInMeters(
 currentCoords.latitude,
 currentCoords.longitude,
 fence.latitude,
 fence.longitude
 );
 if (distance <= fence.radius) {
 return fence; // user is inside this geofence
 }
 }
 return null;
};

Cache the geofences list locally e rinfresca periodicamente piuttosto che prendere su ogni aggiornamento di posizione, che mantiene l'app reattiva e riduce il carico del server.

Ottimizzazione delle prestazioni e della batteria

Il tracciamento della posizione è una delle caratteristiche più resistenti alla batteria sul cellulare. Gli utenti disinstallare un'app che scarica il telefono, quindi l'ottimizzazione non è facoltativa.

  • Utilizza distanzaFilter[[]] – Impostare abbastanza alto per evitare aggiornamenti jittery. Per le applicazioni a piedi, 10 metri è una buona linea di base. Per le applicazioni di guida, 20-50 metri funziona meglio.
  • Ridurre l'accuratezza della posizione quando possibile[[[]] – Per caratteristiche come “ città corrente,” la posizione grossolana (con sede in rete) è sufficiente.
  • Trettle network call[[]] – Buffer punti di posizione in memoria e li gettare a Directus ogni 30 secondi o ogni 100 punti, che viene prima.
  • Guardare quando l'applicazione va a sfondo[[[]] – A meno che la tua applicazione non abbia un caso di uso di sfondo legittimo (navigazione, monitoraggio del fitness), cancellare l'orologioId nel cambia ascolto AppState. iOS terminerà la tua applicazione comunque se utilizza troppa energia di sfondo.
  • Utilizza []] – Accettare una posizione cache se è abbastanza recente.

Apple e Google forniscono sia strumenti di profilazione dell'energia dettagliati. Utilizzare Xcode's Energy Log e Android's Battery Historian per controllare il comportamento della tua app prima della spedizione.

Gestione degli errori e dei casi di bordo

I servizi di localizzazione sono notoriamente inaffidabili. Gli utenti possono negare le autorizzazioni, la modalità aereo può essere attiva, il GPS può essere bloccato all'interno, e i dispositivi più vecchi possono restituire dati stanti o inesatti selvaggiamente.

  • Permesso negato[]] – Mostra un banner non bloccante con un “ Apri Impostazioni” pulsante. Mai forza-quit l'applicazione.
  • Location non available[[]] – Mostra un messaggio come “Location temporaneamente non disponibile. Controlla le impostazioni del dispositivo.” Continua a guardare in modo che l'applicazione si ricuperi automaticamente quando il segnale ritorna.
  • Timeout] – Ripensa fino a tre volte con backoff esponenziale. Se non riesce ancora, rientra in posizione grossolana o nell'ultima posizione conosciuta.
  • Dati di stato o cache[[]] – Confrontare il timestamp della posizione restituita contro []. Se è più vecchio di 60 secondi, scartarlo e attendere il prossimo aggiornamento.

Integra un servizio di registrazione leggero (o semplicemente invia errori a una collezione Directus chiamata [location errors[]]) in modo da poter monitorare i tassi di guasto del mondo reale e migliorare la tua logica iterativamente.

Testare i dispositivi e gli scenari

I simulatori sono utili per l'iterazione rapida dell'interfaccia utente, ma non possono simulare il comportamento reale del GPS. Sempre testare su dispositivi fisici in condizioni variabili: camminare, guidare, all'interno di un edificio, in un tunnel, e con il dispositivo in modalità risparmio energetico. Gli emulatori di Android possono iniettare posizioni di mock tramite i controlli estesi, ma i simulatori di iOS non possono emulare il GPS per la libreria di geolocalizzazione.

Creare un piano di prova che copre questi casi:

  • Installazione fresca e richiesta di autorizzazione di prima volta
  • Deniente il permesso e poi la concessione più tardi tramite le impostazioni
  • Rapido movimento (guida a velocità autostradali)
  • Dispositivo stazionario con alta precisione (dovrebbe produrre un cluster stretto di punti)
  • La transizione di sfondo-terra (ha cancellato la mappa recuperando l'ultima posizione conosciuta?)

Privacy, conformità e fiducia degli utenti

I dati relativi alla posizione sono sensibili. La gestione può portare a multe normative e alla perdita di fiducia degli utenti. Trattalo con la stessa cura delle password o delle informazioni finanziarie.

  • Trasparenza[]] – Spiegare esattamente quali dati di posizione si raccolgono e perché nella vostra politica sulla privacy.
  • Data minimizzazione[[]] – Raccogliere solo il livello di accuratezza di cui hai bisogno. Eliminare i vecchi punti dopo un periodo di conservazione (ad esempio, 30 giorni) tramite un flusso di automazione Directus.
  • Encryption[]] – Servire l'istanza Directus su HTTPS. Considerare la crittografia dei campi di raccolta a riposo se il modello di minaccia lo richiede.
  • Controlli utente[[]] – Fornire un cruscotto in-app in cui gli utenti possono vedere la loro cronologia della posizione e cancellare singoli punti o cancellare l'intera storia.

Per ulteriori informazioni sulla gestione dei dati personali in Directus, consultare il Opzioni di configurazione di sicurezza [].

Ulteriori informazioni: Avanzate Use Cases

Una volta che le basi sono solide, è possibile strato su caratteristiche più sofisticate utilizzando la stessa fondazione.

Condivisione della posizione in tempo reale

Per esempio, un'app di consegna può mostrare il marcatore mobile del corriere sulla mappa del cliente. Il backend riceve la posizione tramite REST e lo spinge verso i clienti iscritti senza inquinare.

Analisi basata sulla localizzazione

I dati di localizzazione aggregati in Directus per generare le mappe di calore, i report di tempo di permanenza o i modelli di route popolari. Il Directus [ Guida di analisi[[] mostra come costruire cruscotti sopra i vostri dati.

Accodamento Offline

Quando la rete non è disponibile, la posizione della coda indica il dispositivo utilizzando AsyncStorage o un database locale come WatermelonDB. Una volta che la connettività riprende, svuota la coda a Directus.

Conclusioni

Implementare il monitoraggio della posizione dell'utente con React Native Maps e l'API Geolocation è un modello ben compreso, ma il diavolo è nei dettagli. Combinando una robusta applicazione frontend con un CMS senza testa come Directus, si ottiene un backend flessibile per la memorizzazione, la ricerca e la gestione dei dati di posizione senza costruire uno strato API personalizzato.