React Native aprovecha el API de geolocalización que ahora es nativo en la web. Este API proporciona métodos como getCurrentPosition, y watchPosition los cuales están disponibles en un pollyfill de React Native.
Para demostrar como usarlo en React Native lo integraremos usando react-native-cli.
Usando react-native-cli generaremos un proyecto usando el siguiente comando:
Si aun no tienes react-native-cli instalado en el sistema instalarlo requiere solo un comando:
$ npm install -g react-native-cli
Y luego generamos el proyecto:
$ react-native init geo-ejemplo
Accediendo a la API de geolocalización
Esta API existe de manera global en el objecto navigator en React Native, justo como en la web. Lo podemos acceder a través de llamar a navigator.geolocation en nuestro código fuente y no hay necesidad de importarlo.
Para efectos de demostrarlo usaremos la función getCurrentPosition de la API de geolocalización. Este método permite a una aplicación móvil pedir permiso a los usuarios para adquirir su ubicación y recibe 3 parámetros que son:
- Un callback para llamada exitosa
- Un callback para llamada fallida
- Un objeto de configuración
navigator.geolocation.getCurrentPosition( posicion => { const ubicacion = JSON.stringify(posicion); this.setState({ ubicacion }); }, error => Alert.alert(error.message), { enableHighAccuracy: true, timeout: 20000, maximumAge: 1000 } );
La llamada de éxito tiene un argumento de posición que es un objeto con las siguientes propiedades en el caso de que transcurrió exitosamente:
{ "timestamp": 1533729980953.91 "coords": { "accuracy": 5, "altitude": 0, "altitudeAccuracy": -1, "heading": -1, "latitude": 37.785834, "longitude": -122.406417, "speed": -1 } }
Ahora para iniciar nuestra aplicación, modificaremos App.js y definiremos un componente clase basico que desplegara el texto “Donde Estoy?”
import React, { Component } from "react"; import { View, Text } from "react-native"; export default class App extends Component { render() { return ( <View> <Text>Donde Estoy?</Text> </View> ); } }
Implementando la API de geolocalización
Ahora implementaremos la función de la API getCurrentPosition en nuestra app. agregando el siguiente código al archivo App.js
import React, { Component } from "react"; import { Platform, StyleSheet, Text, View, Alert, TouchableOpacity } from "react-native"; export default class App extends Component { state = { ubicacion: null }; encontrarCoordenadas = () => { navigator.geolocation.getCurrentPosition( posicion => { const coordenadas = JSON.stringify(posicion); this.setState({ coordenadas }); }, error => Alert.alert(error.message), { enableHighAccuracy: true, timeout: 20000, maximumAge: 1000 } ); }; render() { return ( <View style={estilos.contenedor}> <TouchableOpacity onPress={this.encontrarCoordenadas}> <Text style={estilos.texto}>Donde Estoy?</Text> <Text>Ubicación: {this.state.ubicacion}</Text> </TouchableOpacity> </View> ); } }
Comenzamos importando TouchableOpacity, que es un componente para responder de forma precisa al toque de la pantalla. En una app de React Native, se usa ese componente a menudo y es el equivalente a un botón en el paradigma web. Este componente acepta una propiedad onPress que se ejecuta cuando la función que recibe esta especificada. En nuestro caso encontrarCoordenadas.
encontrarCoordenadas contiene la lógica que definimos al inicio para obtener las coordenadas del usuario. Ademas estamos usando el estado local para mostrar las coordenadas a partir de la información que nos provee el objeto de posición. y el texto “Donde Estoy?” se adquiere un comportamiento clicleable.
Ahora estilizamos un poco nuestra aplicación creando el objeto estilos
const estilos = StyleSheet.create({ contenedor: { flex: 1, justifyContent: "center", alignItems: "center", backgroundColor: "#e1e7ea" }, texto: { fontSize: 20, textAlign: "center", margin: 10 } });
Permisos
En este punto todo lo que hemos hecho no funcionará como es esperado. Para que funcione necesitamos pedirle permiso al usuario para leer su ubicación.
En iOS la geolocalización esta habilitada por defecto cuando creamos el proyecto con react-native-cli. y para usarla necesitamos incluir la llave
<key>NSLocationWhenInUseUsageDescription</key>
en el archivo info.plist adentro del directorio de la app ios.
quedaría mas o menos asi:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>CFBundleDevelopmentRegion</key> <string>en</string> <key>CFBundleDisplayName</key> <string>findCoordsApp</string> [..] <key>NSLocationWhenInUseUsageDescription</key> <string></string> <key>NSAppTransportSecurity</key> <!--See http://ste.vn/2015/06/10/configuring-app-transport-security-ios-9-osx-10-11/ --> [...] </dict> </plist>
para el caso de android es mas simple, basta con agregar la siguiente linea en el archivo android/app/src/AndroidManifest.xml:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
Después de esto la aplicación debería funcionar con normalidad.
No se si me equivoco, creo que tienes un error en la línea 21 cuando haces el setState, ya que en el estado llamaste ubicación a la variable y no coordenadas…
En la línea 36 llamas a ubicación que nunca dejará de ser null.