Crea un módulo nativo en React Native para lectura de sensor de proximidad

Crea un módulo nativo en React Native para lectura de sensor de proximidad

Este artículo muestra cómo crear un módulo nativo en React Native para leer el sensor de proximidad del teléfono celular.

La guía:

  • Explica cómo integrar código nativo de iOS y Android con JavaScript utilizando módulos nativos.
  • Enseña cómo leer el sensor en plataformas para detectar proximidad.
  • Retorna los datos vía callback para el código JS.
  • Crea un listener JS para actualizaciones del sensor.
  • Usa los datos para mostrar/esconder información en la app de ejemplo.
  • Explica diferencias entre las APIs de sensor nativas iOS y Android.
  • Sirve como patrón para integrar recursos avanzados de hardware vía módulos nativos en React Native.


Desarrollo en React Native

React Native es un framework Código abierto que permite el desarrollo de aplicaciones móviles multiplataforma utilizando JavaScript y React. Los desarrolladores lo utilizan ampliamente para crear aplicaciones de iOS y Android con una base de código compartida.

Esto ahorra tiempo y recursos ya que permite a los desarrolladores reutilizar gran parte del código entre las dos plataformas.

Integración con Desarrollo Nativo

En algunos casos, es posible que necesites acceder a funciones nativas específicas de la plataforma que no están disponibles directamente en React Native. Para ello, React Native proporciona un puente (bridge) lo que permite la comunicación entre el código JavaScript y el código nativo de las plataformas. Hay dos formas principales de hacer esto:

  • Native Modules (Módulos nativos): Los desarrolladores pueden crear módulos nativos personalizados en Objective-C (para iOS) o Java (para Android) y luego exponer esos módulos a JavaScript. Esto permite que el código JavaScript llame a métodos nativos directamente para realizar tareas específicas de la plataforma.
  • Native Views (Views Nativas): Además de los módulos nativos, puede integrar componentes de interfaz de usuario nativos en su aplicación React Native. Esto es útil cuando necesita una experiencia de usuario altamente personalizada o desea integrarse directamente con bibliotecas nativas de terceros.
Fuente: https://react-native-course.elazizi.com/about-react-native

Turbo Module y Fabric

En 2018, React Native introdujo dos nuevas arquitecturas para mejorar el rendimiento y la eficiencia:

  • Turbo Module: Turbo Module es una actualización de la arquitectura del módulo nativo que tiene como objetivo mejorar significativamente el rendimiento de JavaScript al llamar a métodos nativos. Utiliza compilación estática para acelerar la comunicación entre JavaScript y el código nativo.
  • Fabric: Fabric es una nueva arquitectura de renderizado que tiene como objetivo mejorar el rendimiento y la capacidad de respuesta de las interfaces de usuario en aplicaciones React Native. Está diseñado para ser más liviano y escalable, lo que hace que las aplicaciones sean más rápidas y eficientes en cuanto a recursos.
Fuente: https://reactnative.dev/architecture/xplat-implementation

Conoce más en: https://reactnative.dev/architecture/overview

Sensor de Proximidad

¿Sabías que entre los diversos sensores que tiene tu celular uno de ellos es el de proximidad? Es a través de este que tu celular apaga la pantalla cuando contestas una llamada y lo acercas a tu cara para no calentarse junto a tu piel.

¿Qué otras aplicaciones podemos tener para este sensor?

- El N26 lo utiliza en su aplicación para ocultar y mostrar los valores.

- Puedes crear una app estilo flap bird.

- Puedes añadir una funcionalidad y pasar páginas de un ebook.

Por lo tanto, creemos una biblioteca en RN para iOS y Android para exponer las API nativas del sensor de proximidad. Pero primero, comprendamos las diferencias entre los sistemas iOS y Android para este escenario: ocultar y mostrar valores en su aplicación.

iOS

En iOS, el retorno de la API del sensor de proximidad es un booleano:

  • true = Near
  • false = Far

Y se comporta, como se muestra en el siguiente gráfico, como un buffer range.

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

La documentación de la API nativa está aquí.

Simuladores iOS

Los simuladores de iOS están incluidos en Xcode, el IDE oficial de Apple. Simulan el sistema operativo iOS y el hardware de dispositivos como iPhone y iPad completamente en software.

Los simuladores son rápidos y fáciles de usar, pero no reproducen con precisión el hardware real. Es posible que algunas API que dependen de hardware específico no funcionen correctamente. Los simuladores son los mejores para probar la lógica y la interfaz de las aplicaciones.

Para probar nuestro módulo en iOS tendremos que utilizar un dispositivo físico ya que el sensor de proximidad no está disponible en el simulador de iOS.

Android

En Android, la API del sensor de proximidad devuelve un valor numérico de 0 a 10 cm, pero en algunos dispositivos también puede devolver un valor booleano.

La documentación de la API nativa Android está aquí.

Emuladores Android

Los emuladores de Android están incluidos en Android Studio, el IDE oficial. Ejecutan una máquina virtual con una versión completa del sistema Android. Emulan tanto software como hardware, incluidos el procesador, la GPU, la cámara y los sensores.

Para probar nuestro módulo en Android, podemos usar el emulador ya que está disponible el sensor de proximidad.

Creando un módulo nativo

Para crear el módulo nativo en React Native, se recomienda que utilicemos la biblioteca react-native-builder-bob.

Es una CLI que nos proporciona un esqueleto de módulo en React Native.

Comencemos con el siguiente comando:

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

Tendremos que responder algunas preguntas y seleccionar la opción del módulo que queremos construir. Elegí un módulo nativo (Native Module) porque quiero migrarlo a la versión más nueva en la próxima oportunidad, que es el Turbo Module.


Así como los idiomas que queremos utilizar en nuestro módulo.


Tras estos pasos ya tendremos nuestro proyecto base generado. En él tenemos las carpetas:

  • iOS y Android: donde se ubicarán los códigos nativos de los módulos.
  • example: donde hay una aplicación de ejemplo para probar el módulo.
  • src: donde quedan los archivos javascript/typescript del módulo.
  • lib: donde quedan los archivos después del build.

Y el resto de archivos son archivos de configuración.


Ese proyecto usa el turbo.build para buildar los paquetes y el yarn workspaces para gestionar las solicitudes de proyectos. Por tanto, en la raíz del proyecto puedes ejecutar el comando:

❯ yarn

Y se instalarán todas las dependencias, incluidos los pods de proyectos de ejemplo.

Y para ejecutar el proyecto de ejemplo, simplemente inserta:

❯ yarn example ios

❯ yarn example android

Manos a la obra


No detallaré cada parte del código, sólo las principales para no extenderme demasiado. No dudes en acceder al repositorio con el código completo y enviarme preguntas y sugerencias.

Código iOS

En el archivo ProximitySensor.m tenemos un método para inicializar las actualizaciones del sensor. Como esta inicialización debe realizarse en el hilo principal, debemos realizar un desencadenador asincrónico en la cola principal. Puedes ver que tenemos un decorador RCT_EXPORT_METHOD que indicará que esta función estará expuesta al hilo JS.


Con eso, tendremos una función callback proximityStateDidChange, que será llamada toda vez que cambie el valor del sensor:

Código Android

En el archivo ProximitySensorModule.java, agregamos la siguiente importación para acceder a las API del sensor.

import android.hardware.Sensor;

Y activamos el sensor de proximidad:


Y así, en la función de callback cuando el sensor cambia, configuramos nuestra lógica para enviar un evento a JS. En JS recibiremos un objeto con la clave distance y otra timestamp con intervalo configurable:

Código JavaScript

Ahora que tenemos eventos con datos de sensores enviados mediante código nativo, podemos crear un listener para escuchar los cambios de los sensores en JS:


Y en nuestra aplicación de ejemplo, podemos consumir este oyente y cuando hay un cambio de proximidad de lejos a cerca y de lejos nuevamente, (is_double_toggle) podemos cambiar el estado de visibilidad del equilibrio:


Funcionamiento en iOS

Aquí vemos nuestro módulo funcionando en el iPhone (dispositivo físico):



Funcionamento en Android (Emulador)

Aquí vemos nuestro módulo funcionando en Android (emulador):

El paquete NPM puede encontrarse aquí.

El repositorio del paquete está aquí. ¿Quién está emocionado/a por convertir este módulo a la nueva arquitectura React Native?


¡Hasta la próxima!

💡
Las opiniones y comentarios emitidos en este artículo son propiedad única de su autor y no necesariamente representan el punto de vista de Listopro.

Listopro Community da la bienvenida a todas las razas, etnias, nacionalidades, credos, géneros, orientaciones, puntos de vista e ideologías, siempre y cuando promuevan la diversidad, la equidad, la inclusión y el crecimiento profesional de los profesionales en tecnología.