Criando um módulo nativo para React Native para leitura do sensor de proximidade

Criando um módulo nativo para React Native para leitura do sensor de proximidade

Este artigo mostra como criar um módulo nativo em React Native para ler o sensor de proximidade do celular.

O guia:

  • Explica como integrar código nativo iOS e Android com JavaScript usando módulos nativos.
  • Lê o sensor nas plataformas para detectar proximidade.
  • Retorna os dados via callback para o código JS.
  • Cria um listener JS para atualizações do sensor.
  • Usa os dados para mostrar/esconder informações no app de exemplo.
  • Explica diferenças entre as APIs de sensor nativas IOS e Android.
  • Serve como guia para integrar recursos avançados de hardware via módulos nativos no React Native.


Desenvolvimento em React Native

O React Native é um framework de código aberto que permite o desenvolvimento de aplicativos móveis multiplataforma usando JavaScript e React. Ele é amplamente utilizado por desenvolvedores para criar aplicativos para iOS e Android com uma base de código compartilhada.

Isso economiza tempo e recursos, uma vez que permite que os desenvolvedores reutilizem grande parte do código entre as duas plataformas.

Integração com Desenvolvimento Nativo

Em alguns casos, pode ser necessário acessar recursos nativos específicos da plataforma que não estão disponíveis diretamente no React Native. Para isso, o React Native fornece uma ponte (bridge) que permite a comunicação entre o código JavaScript e o código nativo das plataformas. Existem duas principais maneiras de fazer isso:

  • Native Modules (Módulos nativos): Os desenvolvedores podem criar módulos nativos personalizados em Objective-C (para iOS) ou Java (para Android) e, em seguida, expor esses módulos para o JavaScript. Isso permite que o código JavaScript chame métodos nativos diretamente para realizar tarefas específicas da plataforma.
  • Native Views (Views Nativas): Além dos módulos nativos, é possível incorporar componentes de interface do usuário nativos em seu aplicativo React Native. Isso é útil quando você precisa de uma experiência de usuário altamente personalizada ou deseja integrar diretamente com bibliotecas de terceiros nativas.
Fonte: https://react-native-course.elazizi.com/about-react-native

Turbo Module e Fabric

Em 2018, o React Native introduziu duas novas arquiteturas para melhorar o desempenho e a eficiência:

  • Turbo Module: O Turbo Module é uma atualização da arquitetura de módulos nativos que visa melhorar significativamente o desempenho do JavaScript ao chamar métodos nativos. Ele faz uso de compilação estática para acelerar a comunicação entre JavaScript e código nativo.
  • Fabric: O Fabric é uma nova arquitetura de renderização que visa melhorar o desempenho e a responsividade das interfaces de usuário em aplicativos React Native. Ele foi projetado para ser mais leve e escalável, tornando os aplicativos mais rápidos e eficientes em termos de recursos.
Fonte: https://reactnative.dev/architecture/xplat-implementation

Saiba mais em: https://reactnative.dev/architecture/overview

Sensor de Proximidade

Você sabia que entre os vários sensores que o seu celular tem, um deles é de proximidade? É através dele que seu celular desliga a tela ao atender uma ligação e aproximar do rosto para não esquentar próximo a sua pele.

Quais outras aplicações podemos ter desse sensor?

- O N26 utiliza em seu app para esconder e mostrar os valores em seu app.

- Você pode criar um app estilo flap bird.

- Você pode adicionar uma funcionalidade e passar páginas de um ebook.

Portanto, vamos criar uma biblioteca em RN para IOS e Android para expor as APIs nativas do sensor de proximidade. Mas antes, vamos entender as diferenças entre os sistemas IOS e Android para esse cenário:

iOS

No iOS, o retorno da API do sensor de proximidade é um boleando:

  • true = Near
  • false = Far

E ele se comporta, conforme o gráfico abaixo, com um buffer range.

Fonte: https://itnext.io/ios-proximity-sensor-as-simple-as-possible-a473df883dc9‌ ‌

A documentação da API nativa está aqui.

Simuladores iOS

Os simuladores iOS são incluídos no Xcode, a IDE oficial da Apple. Eles simulam o sistema operacional iOS e hardware de dispositivos como iPhones e iPads completamente em software.

Os simuladores são rápidos e fáceis de usar, mas não reproduzem com precisão o hardware real. Algumas APIs que dependem de hardware específico podem não funcionar corretamente. Os simuladores são melhores para testar a lógica e interface do app.

Para o teste de nosso módulo no IOS, teremos que usar um dispositivo físico já que o sensor de proximidade não está disponível no simulador IOS.

Android

No Android, o retorno da API do sensor de proximidade retorna um valor numérico de 0 a 10 cm, mas, em alguns aparelhos pode também retornar valor booleano.

A documentação da API nativa android está aqui.

Emuladores Android

Os emuladores Android são incluídos no Android Studio,  a IDE oficial. Eles rodam uma máquina virtual com uma versão completa do sistema Android. Eles emulam tanto software quanto hardware, incluindo processador, GPU, câmera e sensores.

Para o teste de nosso módulo no Android, poderemos usar o emulador já que o sensor de proximidade está disponível.

Criando um módulo nativo

Para criar o módulo nativo em React Native é indicado que usemos a biblioteca react-native-builder-bob.

Ela é uma CLI que nos fornece um esqueleto de módulo em React Native.

Vamos começar com o seguinte comando:

❯ npx create-react-native-library@latest react-native-proximity-sensor

Teremos que responder a algumas perguntas e selecionar a opção de módulo que queremos construir. Escolhi um módulo nativo (Native Module) porque quero em uma próxima oportunidade migrar ela para a versão mais nova que é a Turbo Module.


Assim como as linguagens que queremos usar em nosso módulo.


Após estes passos, teremos nosso projeto base gerado. Nele temos as pastas:

  • ios e android: onde ficarão os códigos nativos dos módulos.
  • example: onde fica uma aplicação de exemplo para teste do módulo.
  • src: onde ficam os arquivos javascript/typescript do módulo.
  • lib: onde os arquivos transpilados ficam após o build.

E o restante dos arquivos são de configuração.


Esse projeto usa o turbo.build para buildar os pacotes e o yarn workspaces para gerenciar as aplicações do projeto. Portanto, na raiz do projeto você pode rodar o comando:

❯ yarn

E todas as dependências serão instaladas, inclusive os pods do projeto exemplo.

E para rodar o projeto exemplo é só rodar:

❯ yarn example ios

❯ yarn example android

Mãos à obra

Não irei detalhar cada parte do código, somente as principais para não me prolongar muito. Fique à vontade para acessar o repositório com o código completo e me enviar perguntas e sugestões.

Código iOS

No arquivo ProximitySensor.m temos um método para inicializar as atualizações do sensor. Como essa inicialização tem que ser feita na thread principal, precisamos fazer um disparo assíncrono para a fila main. Você pode perceber que temos um decorator RCT_EXPORT_METHOD que vai indicar que essa função será exposta para a thread JS.


Com isso, teremos uma função de callback proximityStateDidChange, que será chamada toda vez que o valor do sensor alterar:

Código Android

No arquivo ProximitySensorModule.java, adicionamos a seguinte importação para ter acesso às APIs de sensores.

import android.hardware.Sensor;

E ativamos o sensor de proximidade:


E assim, na função de callback quando o sensor sofre alteração, montamos nossa lógica para enviar um evento para o JS. No JS receberemos um objeto com a chave distance e outra chave timestamp com um intervalo configurável:

Código Javascript

Agora que temos os eventos com os dados do sensor sendo enviados pelo código nativo, podemos criar um listener para escutar as alterações do sensor no JS:


E no nosso aplicativo de exemplo, podemos consumir esse listener e quando houver uma alteração de proximidade de longe para perto e para longe novamente, (is_double_toggle) podemos alterar o estado de visibilidade do saldo:


Funcionamento no iOS

Aqui vemos nosso módulo em funcionamento no Iphone (aparelho físico):



Funcionamento no Android (Emulador)

Aqui vemos nosso módulo em funcionamento no Android (emulador):

O pacote NPM pode ser encontrado aqui.

O repositório do pacote está aqui. Quem anima de converter esse módulo para a nova arquitetura do React Native? Fique à vontade para enviar sua contribuição!

Até a próxima, pessoal!

💡
As opiniões e comentários expressos neste artigo são de propriedade exclusiva de seu autor e não representam necessariamente o ponto de vista da Revelo.

A Revelo Content Network acolhe todas as raças, etnias, nacionalidades, credos, gêneros, orientações, pontos de vista e ideologias, desde que promovam diversidade, equidade, inclusão e crescimento na carreira dos profissionais de tecnologia.