Desarrollando aplicaciones móviles nativas con React Native

Los desarrolladores front normalmente trabajamos dentro del ecosistema de los navegadores web. Por lo general, el desarrollo de aplicaciones móviles nativas ha sido un mundo aparte para nosotros.

Pero parece que los tiempos están cambiando y, con la promesa de poder programar aplicaciones tanto para iOS como para Android con un solo lenguaje de programación (en este caso Javascript), han nacido los llamados Cross-Platforms frameworks, como Ionic, NativeScript y React Native, de modo que los frontend que queremos matar el gusanillo de hacer apps nativas con JS ya lo tenemos más fácil.

En este post vamos a explorar las posibilidades de desarrollar aplicaciones con React Native (RN) y con Expo SDK/XDE. ¡Veamos cómo!

React native: las seis W

What?

React Native es un framework que permite a los desarrolladoresimplementar apps nativas para dispositivos móviles utilizando Javascript. De momento los sistemas operativos mínimos soportados son: Android 4.1 (API 16) y >= iOS 8.0.

Why/How?

¡Espera! ¿Cordova no permitía hacer lo mismo? ¿Qué nos aporta RN? La principal diferencia entre RN y las apps basadas en Cordova es que en Cordova las apps se ejecutan dentro de una webview, mientras las RN apps renderizan utilizando views nativas.

Las RN apps tienen acceso directo a todas la APIs y views nativas que ofrecen los sistemas operativos nativos. De forma que la experiencia de usuario y el rendimiento es el mismo de una aplicación nativa.

When/Who/Where?

En Marzo de 2015, Facebook anunciaba en la F8 que React Native estaba disponible en Github. Y hay importantes aplicaciones que ya lo están utilizando:

Arquitectura de ejecución

Lo primero que se podría suponer es que React Native compila código JS en el correspondiente código nativo directamente. Pero esa empresa es bastante dura de realizar, ya que Java y Objective C/Swift son lenguajes fuertemente tipados mientras que Javascript no lo es.

En lugar de eso, RN hace algo más inteligente: React Native es, en esencia, un conjunto de componentes React, donde cada uno de ellos tiene su correspondiente equivalente en views y componentes nativos.

Por ejemplo, el componente nativo TextInput tiene su correspondiente en RN que puede ser importado dentro del código JS y ser utilizado como cualquier componente React. De ahí que el programador frontend escriba código como si estuviera desarrollando una web en ReactJS. Hay tres componentes ‘behind the scenes’ cuando se ejecuta una RN app:

  1. Módulos/códigos nativos: son todos los módulos necesarios (tanto de iOS como de Android) para que cuando hagamos nuestra RN app no tengamos que preocuparnos de escribir código nativo.
  2. Javascript VM: es la Virtual Machine de Javascript que ejecutará nuestro código JS. Tanto en iOS como en Android se utiliza JavascriptCore, que es el motor Javascript que utiliza Webkit para Safari. Esta pieza de software ya viene incluida en los dispositivos iOS, pero no en Android. Por lo que RN empaquetará esta pieza dentro del apk, lo que incrementa el tamaño en 3-4 megabytes.
  3. React Native Bridge: es un bridge React Native escrito en C++/Java y es responsable de comunicar los hilos de Javascript y de nativo. Entre ellos se hablan en un protocolo de mensajes.

Menos teoría, ¡montemos el entorno y tiremos código!

Hay principalmente dos formas de trabajar con React Native:

  1. La oficial:  la llevamos a cabo instalando la utilidad node create-react-native-app e instalando en el móvil la Expo app para visualizar las aplicaciones que se van desarrollando. Con esta vía es posible que requieras de ajustes en código nativo (XCode/Android Studio) sobre todo a la hora de hacer releases y publicar la aplicación. Por tanto, requiere de tener cierto conocimiento de las plataformas nativas o al menos tener algún compañero cerca con conocimientos de ello.
  2. La otra forma es utilizar Expo, que lo forman un grupo de desarrolladores que han creado un conjunto de herramientas que facilitan el trabajo con React Native. Por ejemplo, con la herramienta de línea de comando Expo CLI se puede crear ‘from scratch’ una app RN:

 

 

Con Expo se hace más fácil las pruebas en simuladores y en dispositivos. Además, distribuyen una librería Expo SDK que facilita integrar capacidades de los móviles como Push Notifications, Facebook login, Instant updating, etc.

También tiene la posibilidad de publicar tus aplicaciones bajo urls que puedes compartir de forma fácil. Y, sobre todo, aísla completamente al programador de conocer lenguajes de programación nativos.

NOTA: Existe la versión desktop de esta herramienta: Expo XDE.

En todos los casos se obtiene un código QR que, escaneándolo desde la Expo App, se puede ejecutar nuestro código en los dispositivos físicos.

También disponemos de las ventajas de tener hot reloading y debugging con Chrome. El debugging con Chrome se consigue haciendo que el código JS se ejecute dentro de Chrome en vez de en JavascriptCore y se comunique con los módulos nativos vía Websocket.

Hola Mundo

Para que veamos algo de código y os convenza de que al final se programa todo como si fuera una aplicación web en React, hemos hecho una aplicación simple que navega entre dos pantallas con contenido de texto e imágenes:

App.js

import React from 'react';
 
import FirstScreen from './src/components/FirstScreen';
import SecondScreen from './src/components/SecondScreen';
 
import { createStackNavigator } from 'react-navigation';
 
 
const RootStack = createStackNavigator({
 First: { screen: FirstScreen },
 Second: { screen: SecondScreen },
},
{
 initialRouteName: 'First',
});
 
export default class App extends React.Component {
 render() {
   return <RootStack />;
 }
}

FirstScreen.js

import React from 'react';
import { StyleSheet, Text, View, Image, Dimensions, TouchableOpacity } from 'react-native';
import AnsHeader from './AnsHeader';
 
export default class FirstScreen extends React.Component {
 
   onPressNext() {
       const { navigate } = this.props.navigation;
       navigate('Second');
   }
 
   render() {
       return (
           <View style={styles.container}>
 
               <AnsHeader />
 
               <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
                   <Text style={{ fontSize: 30 }}>What is Agile?</Text>
                   <Image resizeMode='contain' style={{ width: Dimensions.get('window').width - 50, height: 200 }} source={{ uri: 'http://www.agilenutshell.com/assets/what-is-agile/incrementally-over-all-at-once.png' }} />
                   <Text style={{ padding: 10 }}>Agile is a time boxed, iterative approach to software delivery
                   that builds software incrementally from the start of the project, instead of trying to deliver
         it all at once near the end.</Text>
               </View>
 
               <TouchableOpacity onPress={this.onPressNext.bind(this)}>
                   <View style={{ width: 150, marginBottom: 10, backgroundColor: '#dcdcdc', alignItems: 'center', borderRadius: 10 }}>
                       <Text style={{ margin: 15 }}>Learn More</Text>
                   </View>
               </TouchableOpacity>
 
           </View>
       );
   }
}
 
const styles = StyleSheet.create({
   container: {
       flex: 1,
       backgroundColor: '#fff',
       alignItems: 'center',
       justifyContent: 'space-between',
   },
});

Puedes encontrar en este Github toda la información.

Lo hemos hecho con el camino oficial: usando create-react-native-app y sólo utilizando como librerías de terceros la de React Navigation para implementar la navegación entre las dos pantallas.

Flexbox para maquetar los layout y CSS para estilos

Los componentes RN pueden organizar el layout de sus hijos utilizando el algoritmo Flexbox, que se diseñó para proporcionar un layout que fuera consistente para distintos tamaños de pantalla. Flexbox funciona en RN de la misma forma que lo hace con el CSS para la web, con algunas excepciones.

Respecto al estilo de los componentes no hay ninguna sintaxis especial. Todos los componentes del core de RN aceptan una property “style”.  Los valores que se pueden meter en style casi siempre tienen una equivalencia a cómo funciona CSS en web, excepto que los nombres son escritos utilizando camel case, es decir, backgroundColor en vez de background-color.

Ejemplo:

<View style={{ width: 150, marginBottom: 10, backgroundColor: '#dcdcdc', alignItems: 'center', borderRadius: 10 }}>
     <Text style={{ margin: 15 }}>Learn More</Text>
</View>

Ejemplo de aplicación en producción

Como ejemplo de aplicación más avanzada y desarrollada con Expo podéis consultar la Marvel Oldies app en Github.

Disponible sólo para Android, si os instaláis la Expo app la podéis probar con éste código QR:

Y también podéis bajaros la app desde Play Store.

En este caso al ser desarrollada con Expo, además de que el flujo de trabajo fue más cómodo , a la hora de la publicación de la aplicación en la Play Store de Google ha sido más fácil , sobre todo a la hora de firmar el apk .

Mi experiencia desarrollando una app RN

Después de llevar un tiempo desarrollando una app RN, estas son mis conclusiones:

  • El entorno de trabajo es costoso de instalar (con Expo ese tiempo se reduce).
  • El flujo de trabajo no es tan fluido como en web, el hot reloading y el debugging aún no son tan fluidos. Los simuladores se cuelgan de vez en cuando.
  • No es 100% cross-platform: la promesa de escribir Javascript y que se comporte de la misma forma para iOs y Android NO es del todo cierta. En la documentación hay muchos properties donde se hace diferencia entre plataformas, y es necesario, en algunas ocasiones, el uso de Platform para conseguir el mismo look en ambas plataformas. Ejemplo:
style: {
    marginTop: Platform.OS === 'ios' ? 40 : 30
}
  • La comunidad RN es muy prolífica y tiene actualizaciones continuas (lo que, de momento, es un buen síntoma). En el siguiente catálogo de recursos RN podéis comprobar el enorme número de  librerías de terceros disponibles.
  • La posibilidad de integrar componentes RN dentro de aplicaciones nativas existentes es muy interesante. Es decir, se puede realizar una aplicación nativa con componentes en RN y los componentes que requieran animaciones o mejor performance en código nativo.
  • Expo SDK/XDE es la mejor opción para no tener la necesidad de tirar nunca código de lenguajes nativos.

En resumen, RN ofrece realizar apps no demasiado complejas para iOs & Android con Javascript y, ahora mismo, es una apuesta segura a la hora de decidirse para un desarrollo cross-platform. ¡Espero que la exploréis y compartamos experiencias!

Referencias

Programador-Explorador. Tras una larga etapa javera actualmente explorando el mundo frontend. He visto de todo: atacar naves en llamas más allá de Orión, rayos C brillar en la oscuridad cerca de la Puerta de Tannhäuser, y de todo me quedo con las arquitecturas KISS y el código bien comentado/autocomentado.

Ver toda la actividad de Javier Escacena

Escribe un comentario