Utilizando mapas no React Native com Mapbox

React 19 de Jun de 2018

Se existe algo que é sempre utilizado em aplicativos mobile é o mapa. Mostrar onde você está é apenas o começo, hoje em dia as possibilidades são das mais variadas e conta apenas com a sua imaginação.

No post de hoje vou apresentar uma maneira de adicionar um mapa ao seu aplicativo React Native, com um mínimo (sim, tem um pouquinho) de burocracias. Para isso usaremos o Mapbox, uma API muito robusta que vem crescendo no meio da comunidade React Native.

Primeiro passo

Vamos ter que criar uma conta no site da Mapbox. Uma vez criada a conta, basta copiar o access token, na área “Get your access token”:

Área do site Mapbox para pegar o access token

Instalações

Com o access token em mãos, vamos configurar nosso App com o React Native:

react-native init RocketMap

Instalaremos também o package do Mapbox:

npm install @mapbox/react-native-mapbox-gl

Com essa lib, diferente da maioria não vamos fazer o link automático para Android e IOS, vamos fazer manualmente, pois a lib apresenta alguns problemas um pouco complexos para resolver quando é feito o link através do comando react-native link.

Para configurar corretamente a lib para funcionar no Android e IOS, siga o passo a passo para cada plataforma logo abaixo:

Android

Vamos começar a configuração para Android no arquivo android/app/build.gradle , nele desça até perto do final e procure o objeto dependencies, dentro dele terão algumas linhas começando pela palavra compile, dentro desse objeto, adicione o seguinte trecho:

implementation project(':mapbox-react-native-mapbox-gl') {
  implementation ('com.squareup.okhttp3:okhttp:3.6.0') {
    force = true
  }
}

Abra agora o arquivo android/settings.gradle, e nele adicione no final as linhas:

include ':mapbox-react-native-mapbox-gl'
project(':mapbox-react-native-mapbox-gl').projectDir = new File(rootProject.projectDir, '../node_modules/@mapbox/react-native-mapbox-gl/android/rctmgl')

E agora pra finalizar (ebaaa \o/) vamos fazer algumas modificações no arquivo android/app/src/main/java/com/<nome_do_projeto>/MainApplication.java, a primeira delas é adicionar a importação do Mapbox logo abaixo da importação do SoLoader, ficando assim:

...
import com.facebook.soloader.SoLoader;
import com.mapbox.rctmgl.RCTMGLPackage;
...

Feito isso falta apenas instanciar a classe do Mapbox e para isso procure o método getPackages, e dentro dele, logo abaixo da linha new MainReactPackage() adicione o seguinte código:

new RCTMGLPackage()

Obs.: Não se esqueça de adicionar uma  vírgula (,) no final da linha do MainReactPackage.

E assim finalizamos a configuração para o Android, agora falta pouco, só configurar para o IOS e partir pro código, mas antes de prosseguir faça o teste de rodar a aplicação no Emulador do Android para verificar se não ocorre nenhum erro na compilação.

IOS

Para instalar o MapBox no iOS vamos utilizar o CocoaPods que é uma ferramenta para controlar dependências de projetos em iOS. Para instalar o CocoaPods vou utilizar o HomeBrew:

brew install cocoapods

Agora vamos inicializar o CocoaPods na pasta ios do nosso projeto React Native, para isso, acesse essa pasta do seu projeto pelo terminal e rode o seguinte comando:

pod init

Isso criará um arquivo chamado Podfile na raiz da pasta ios e agora dentro desse arquivo você deve adicionar as seguintes linhas logo abaixo do trecho target 'NomeDoSeuApp' do:

# Flexbox Layout Manager Used By React Natve
pod 'yoga', :path => '../node_modules/react-native/ReactCommon/yoga/Yoga.podspec'

# React Native
pod 'React', path: '../node_modules/react-native', subspecs: [
  # Comment out any unneeded subspecs to reduce bundle size.
  'Core',
  'DevSupport',
  'RCTActionSheet',
  'RCTAnimation',
  'RCTBlob',
  'RCTCameraRoll',
  'RCTGeolocation',
  'RCTImage',
  'RCTNetwork',
  'RCTPushNotification',
  'RCTSettings',
  'RCTTest',
  'RCTText',
  'RCTVibration',
  'RCTWebSocket',
  'RCTLinkingIOS'
]

# Mapbox
pod 'react-native-mapbox-gl', :path => '../node_modules/@mapbox/react-native-mapbox-gl'

Ainda dentro desse mesmo bloco, remova o seguinte trecho de código:

target 'NomeDoSeuApp-tvOSTests' do
  inherit! :search_paths
  # Pods for testing
end

Agora, volte ao terminal e execute o comando pod install. Esse comando levará um tempo então aproveite pra pegar um café 🙂

E para testar o funcionamento, rode o projeto no Simulador do IOS para garantir que não estão ocorrendo erros no processo de compilação.

Pronto, agora você já está pronto para usar o MapBox no React Native, então boooora pro código!

Utilizando Mapbox no React Native

Agora sim!! E como sempre, vou dividir em partes e ir comentando.

Fazemos as importações necessárias e definir o access token que o Mapbox nos disponibilizou:

import React, { Component } from 'react';
import { View, StyleSheet } from 'react-native';
import MapboxGL from '@mapbox/react-native-mapbox-gl';

MapboxGL.setAccessToken('Coloque seu token aqui');
Não vai me esquecer de alterar o “Coloque seu token aqui” pelo seu access token ein!!

Criamos nosso componente e definimos um ponto no nosso mapa. A renderização do mapa é feita pelo componente MapboxGL.MapView, nele podemos definir algumas propriedades.

No nosso caso definimos um mapa com tema Dark e mostramos a localização do usuário, definimos a posição inicial em um Array onde a longitude é -49.6446024 e a latitude é -27.2108001.

Já o renderAnnotations, ficou responsável por renderizar um ponto sobre o mapa e quando clicado mostra um Callout.

export default class App extends Component {
  renderAnnotations() {
    return (
      <MapboxGL.PointAnnotation
        id='rocketseat'
        coordinate={[-49.6446024, -27.2108001]}
      >
        <View style={styles.annotationContainer}>
          <View style={styles.annotationFill} />
        </View>
        <MapboxGL.Callout title='Rocketseat House' />
      </MapboxGL.PointAnnotation>
    )
  }

  render() {
    return (
      <MapboxGL.MapView
        centerCoordinate={[-49.6446024, -27.2108001]}
        style={styles.container}
        showUserLocation
        styleURL={MapboxGL.StyleURL.Dark}
      >
      {this.renderAnnotations()}
      </MapboxGL.MapView>
    );
  }
}

Por fim algumas estilizações, como o ponto sobre o mapa:

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  annotationContainer: {
    width: 30,
    height: 30,
    alignItems: 'center',
    justifyContent: 'center',
    backgroundColor: 'white',
    borderRadius: 15,
  },
  annotationFill: {
    width: 30,
    height: 30,
    borderRadius: 15,
    backgroundColor: '#7159C1',
    transform: [{ scale: 0.8 }],
  }
});

Feito isso vamos executar o nosso projeto:

react-native run-android

Voila!!

Simples, não???

AH, se você estiver usando um emulador lembre-se de habilitar o GPS!! Eu esqueci e fiquei alguns minutos arrancando os cabelos da cabeça.

It’s over

Como você deve ter percebido, não tem muito segredo fazer o Mapbox funcionar. Talvez uma das coisas que “pega” nele é limitar a 50 mil visualizações e depois disso você paga uma taxa, mas até lá conseguimos brincar bastante.

Outra opção muito comum na comunidade é o react-native-maps mas por sua configuração ser bem mais burocrática vamos evita-lo nesse post 🙂

Se existe alguma dúvida quanto ao código, dê uma olhada minicurso gratuito de React Native que preparamos.

Que tal você comentar o que achou? Sugerir alguma coisa? Só não esqueça de compartilhar com seus amigos devs!!

Projeto no github: https://github.com/Rocketseat/blog-react-native-map

Bye, Bye!!

Marcadores