React Native Maps: Cómo instalar y usar la librería de mapas en iOS y Android [2020]

Los mapas se han convertido en una de las interfaces más populares de muchas de las aplicaciones que tenemos instaladas en nuestros teléfonos. Aprender a trabajar sobre mapas, representar la información de forma adecuada y crear una buena interfaz de navegación resulta cada vez más importante.

En este post veremos cómo integrar Google Maps en una aplicación desarrollada con React Native usando la librería react-native-maps para iOS y Android. Para desarrollar un ejemplo lo más realista posible, recrearemos una interfaz del estilo Uber utilizando un Bottom Sheet.

Al final del post conseguiremos desarrollar una aplicación como esta de aquí.

Creación del proyecto

Para este proyecto vamos a utilizar Expo para agilizar el proceso de instalación y facilitar que cualquier persona que quiera descargar el repositorio pueda probar la aplicación fácilmente. Si todavía no tenéis expo instalado podéis seguir la guía de instalación oficial donde lo explica perfectamente.

Lo primero que haremos es crear un proyecto en blanco utilizando la cli de expo.

Instalar la librería react-native-maps con Google Maps

Una vez creado el proyecto el siguiente paso es añadir la librería de mapas para ello podemos utilizar el siguiente comando.

Para instalarlo con un proyecto de react native sin expo lo podremos hacer con siguiente comando.

La diferencia entre el primer comando y el segundo es que usando el cli de Expo nos aseguramos de utilizar la última versión de la librería compatible con Expo.

Cabe mencionar que podemos utilizar la librería de react-native-maps tanto con Apple Maps como con Google Maps. En este tutorial nos centraremos en utilizar Google Maps como proveedor de mapas, pero los pasos para integrar Apple Maps son muy similares.

Obtener la API Key de Google Maps

Para poder utilizar Google Maps en nuestra aplicación será necesario habilitar el SDK de iOS y Android en un proyecto de Google con una cuenta de facturación activa en Google Cloud Console y generar una API key para añadirla al código de nuestra aplicación.

Vamos a ver paso a paso cómo obtener la API Key de Google Maps.

1. Lo primero que haremos será entrar en Google Cloud Console y crear un nuevo proyecto al que llamaremos google-maps-example-reboot.

2. Una vez creado dentro de la biblioteca de apis y servicios será necesario habilitar el Maps SDK de Android y el Maps SDK de iOS

3. Una vez habilitados los sdks será necesario crear una clave de API, para ello vamos al Panel de control → Crear Credenciales → Clave de API

4. Una vez creada la clave de API es muy recomendable sobre todo en un proyecto de producción limitarla a las librerías que queremos usar  y a las aplicaciones que tendrán permiso para usarlas usando la huella digital de la aplicación y el bundle indentifier.

Con esto obtenemos el API Key y ahora falta añadirlo a nuestra aplicación. En función de si estamos utilizando expo o un proyecto bare cambiará la forma de hacerlo.

Añadir la API Key en Expo

En el caso de Expo simplemente vamos al app.json y añadimos lo siguiente:

Añadir la API Key en Android

Si se trata de un proyecto Bare, en Android será necesario añadir el API Key en google_maps_api.xml  en la ruta android/app/src/main/res/values.

Añadir la API Key en iOS

En iOS tendrás que editar el archivo AppDelegate.m para incluir el siguiente fragmento.

Es importante señalar que al usar permisos de localización deberás indicar a Apple por qué necesitas acceder a la ubicación del usuario, de lo contrario Apple rechazará tu aplicación cuando la subas a la App Store. Esto se puede hacer en el archivo Info.plist  editando el campo de NSLocationWhenInUseUsageDescription explicando de forma clara y concisa por qué necesitas conocer la ubicación.

Añadir y personalizar un mapa en React Native

Ahora que ya tenemos la librería de mapas integrada vamos a empezar por crear una pantalla con la visualización del mapa y personalizar el estilo con las diferentes opciones que nos proporciona. Para ello vamos a crear un componente Map.js  como el siguiente.

Como podemos ver el componente principal es MapView  que cuenta con multiples props para personalizar su comportamiento. En este caso los más importantes son provider donde le indicamos que queremos utilizar Google Maps, initialRegion que será la localización que cargará el mapa en un inicio, mapType donde podemos definir el tipo de mapa que se carga y por último customMapStyle donde indicaremos el estilo personalizado del mapa que queremos utilizar.

Si miramos en la documentación oficial de google vemos que podemos personalizar prácticamente todos los elementos del mapa, en este caso buscamos realizar una interfaz bastante minimalista para ello utilizaremos los siguientes estilos.

Personalizar un mapa de Google puede llegar a resultar tedioso, por eso existen páginas como Snazzymaps que reúnen plantillas con diferentes estilos que podemos copiar directamente sus atributos y usarlas como base.

Añadir Marcadores a Google Mapas en React Native

Lo siguiente que haremos será añadir marcadores a nuestro mapa. Para ello crearemos una constante MARKERS_DATA con la siguiente estructura.

Una vez tenemos nuestros datos preparados podemos añadirlos al mapa importando el componente Marker que nos da la librería de mapas y añadirlos dentro de la MapView. Para ello usaremos una función de Array.map juntamente con la estructura de datos MARKERS_DATA que hemos creado.

¡Voilà! Ya tenemos nuestros marcadores sobre el mapa. Pero todavía parece como cualquier mapa estándar de Google Maps, así que en el siguiente paso vamos a darle personalidad customizando el estilo de los marcadores.

Personalizar los marcadores de Google Maps en React Native

La propia librería de react-native-maps incluye varios prop para personalizar el estilo de los marcadores, pero una de las mejores opciones si quieres crear marcadores completamente personalizados es utilizar el componente Marker como un wrapper y crear un componente propio con el estilo que queramos.

Para seguir con la interfaz minimalista queremos crear unos marcadores circulares de diferentes colores en función de la ubicación y que tengan la capacidad de animarse aumentando su tamaño cuando es seleccionado.

Vamos a crear el componente CustomMarker y un hook useMarkerAnimation para gestionar la interacción de la animación.

Para gestionar las animaciones hemos añadido las librerías de Reanimated y Redash.

Finalmente lo remplazamos en la vista de mapa por el Marker de la librería

Listo. Ya tenemos nuestros marcadores personalizados en nuestra aplicación de mapas. Pero todavía queda un paso fundamental: necesitamos poder navegar entre los diferentes marcadores. Para ello crearemos una interfaz basada en un Bottom Sheet similar al que encontramos en aplicaciones como Uber o Google Maps desde donde gestionaremos la navegación entre marcadores.

Gestionar la navegación por el mapa

Vamos a ver cómo podemos navegar por el mapa usando tanto la función de animateCameracomo la función de animateToRegion. Para ello deberemos crear una referencia del mapa para poder utlizarla y llamar a estas funciones, en nuestro caso hemos decidido crear un hook para gestionar está lógica.

Como podemos ver en el código las funciones son bastante sencillas. A animateCamera le pasamos el centro con la latitud y la longitud el Zoom y el tiempo que tardará la animación. En el caso de animateToRegion es muy similar pero en cambio de utilizar el Type Camera utiliza el Type Region.

En nuestro caso también le hemos añadido un setSelectedMarker para poder realizar la ampliación del marcador cuando la cámara utilice este como centro.

Para utilizar el hook simplemente tenemos que añadirlo en nuestro componente de Mapa, pero antes de eso crearemos el componente por encima del mapa para poder utilizar las funciones del hook.

Concretamente vamos a crear un componente Bottom Sheet con el listado de localizaciones y cuando se pulse encima de una de estas la cámara se moverá a ese punto y el marcador seleccionado se ampliará. Para el componente hemos utilizado la librería 'react-native-scroll-bottom-sheet' que utiliza Reanimated para gestionar las animaciones del componente.

También añadiremos un menú superior que nos permitirá reiniciar el estado de nuestro mapa.

Finalmente el componente de mapa quedaría así:

Con esto tendríamos una aplicación de mapas con una interfaz muy simple que nos permite gestionar la navegación entre los diferentes puntos de interés de forma muy intuitiva. Sobre esta base se pueden construir productos mucho más complejos, pero es un buen punto de partida si estás desarrollando una aplicación de mapas en React Native en 2020.

El proyecto completo se encuentra disponible en GitHub para que podáis descargarlo y trabajar sobre él.