Saltar a contenido

architecture-it/native-web-bridge

Librería funcional que contiene utilidades y handlers para utilizar en aplicaciones React Native o React donde se requiera consumir un Webview para renderizar una página web y llevar a cabo una comunicación entre ambas aplicaciones, pudiendo utilizar esta comunicación para llevar a cabo diferentes funcionalidades.

Comunicación y Mensajes

Tradicionalmente, además de renderizar un webview en la aplicación, se suele requerir comunicación entre ambas aplicaciones. Para ello se plantea a traves de ésta librería un estándar de mensaje que permite definir, además de su contenido, que tipo de mensaje se envía. De esta forma podremos actuar en base al tipo de mensaje que se recibe, por ejemplo ejecutar un flujo de autorización si recibimos un mensaje de tipo "token".

Instalación

Como se menciona al comienzo, esta librería se puede (debe) utilizar en ambos lados de la comunicación, es decir, en la aplicación React Native y en la librería React que proporciona la página web que se consume desde el webview.

Para poder instalar la librería, se debe utilizar el manejador de paquetes que el proyecto utilice, por ejemplo yarn o pnpm.

// Utilizar el manejador de paquetes que utilice su proyecto
yarn add @architecture-it/native-web-bridge
pnpm add @architecture-it/native-web-bridge
npm i @architecture-it/native-web-bridge

IWebviewMessage

En la librería el tipado del mensaje se declara bajo la interface IWebviewMessage, y contiene dos propiedades: type y content.

La propiedad type define los diferentes tipos de mensajes que van a existir en la comunicación entre la app y el webview. La misma es customizable, para que cada uno pueda desde la implementación declararle el tipado que considere correcto en base a su necesidad. De forma predefinida, todas las interfaces de las funciones de ésta librería que declaran la propiedad message utilizando la interface de mensaje, utilizan TypeEvent como tipo por default, en caso de utilizar un tipado custom deberá especificarlo.

La propiedad content determina el contenido real del mensaje y es de tipo string, siguiendo con el ejemplo previo podría ser el token de autenticación del usuario.

Ejemplo de implementación con el tipado por default (TypeEvent)

const message: IWebviewMessage {
    type: "token"
    content: "user token"
}

Ejemplo de implementación con tipado custom

const type MessageType = "login" | "logout"

const message: IWebviewMessage<MessageType> {
    type: "login"
    content: "Se inició sesión en la aplicación"
}

IDefaultMessages

Se deja a disposición una interface que permite definir un listado de mensajes default así como también una constante con mensajes que pueden ser considerados generales para cualquier implementación.

Las propiedades del objeto que define esta interfaz deberán ser del tipo previamente mencionado IWebviewMessage. Y al igual que se describió, en caso de ser necesario el tipo de la propiedad type se puede customizar.

Ejemplo de implementación de un mensaje default con el tipado estándar:

const message = DEFAULT_MESSAGES.connection;

Ejemplo de implementación de la interfaz con un tipado custom:

type customType = "login";

const CUSTOM_DEFAULT_MESSAGES: IDefaultMessages<customType> = {
  login: {
    type: "login",
    content: "Inicio de sesión",
  },
};

const message = CUSTOM_DEFAULT_MESSAGES.login;

Handlers

Se deja a disposición cinco funciones o handlers que permitirán manejar la comunicación entre la app mobile y la web con mayor facilidad y simpleza, tanto para enviar mensajes como para recibirlos desde cualquiera de los dos lados.

postMessageToWebview()

Permite enviar mensajes al webview desde la app mobile.

Además del mensaje en sí mismo (que debe ser del tipo IWebviewMessage) se le debe pasar la referencia del Webview y el origen del mismo (para configurar privacidad de comunicación en la mensajería).

Ejemplo de implementación:

const webviewRef = useRef<WebView>(null);
const origin = "http://localhost:3000";
const message: IWebviewMessage {
    type: "token"
    content: "user token"
};

postMessageToWebview({ webviewRef, message, origin });

postMessageToApp()

Permite enviar mensajes a la app mobile desde la web.

Para utilizar ésta función sólo es necesario pasarle el mensaje que se desea enviar.

Ejemplo de implementación:

const message: IWebviewMessage {
    type: "authorized"
    content: "usuario autorizado"
};

postMessageToApp({ message });

getMessageFromApp()

Permite recibir en la web los mensajes que llegan desde la app mobile.

Ésta función espera recibir dos propiedades. Por un lado el evento de mensaje original, desde el cual se va a extraer el mensaje. Por otro lado la acción (función) que se va a ejecutar una vez que se parsee el mensaje, permitiéndonos utilizarlo para llevar a cabo la lógica que se desee en base a su contenido.

Ejemplo de implementación:

const handleMessageListener = (message: IWebviewMessage) => {
    if (message.type === "alert") {
        alert("Soy una alerta");
    }
};

getMessageFromApp({ nativeEvent: event, action: handleMessageListener });

getMessageFromWebview()

Permite recibir en la app mobile los mensajes que llegan desde la web.

La utilización de ésta función es igual a la anterior. Se le deberá pasar el evento original del mensaje y la acción que consumirá ese mensaje para llevar a cabo la funcionalidad que necesitemos.

Ejemplo de implementación:

const handleMessageListener = (message: IWebviewMessage) => {
    if (message.type === "unauthorized") {
        alert("No está autorizado a ver el contenido.")
    }
};

getMessageFromWebview({ event, action: handleMessageListener })}

refreshWebview()

Esta función permite recargar el webview.

Se le deberá pasar a través de las propiedades la referencia del webview que se esté utilizando y se quiera recargar.

Ejemplo de implementación:

const webviewRef = useRef<WebView>(null);

refreshWebview({ webviewRef });

Utilidades

El mensaje que se envía en la comunicación, debe ser de tipo string. Para ello se disponibilizan dos funciones que permiten formatear el mensaje para su correcto envío y posterior consumo.

stringifyWebviewMessage()

Toma el mensaje en el formato o tipo original (IWebviewMessage) y lo convierte a string para poder ser enviado.

Ejemplo de implementación:

const stringifyMessage = stringifyWebviewMessage({ message });

parseWebviewMessage()

Toma el mensaje en formato string y lo convierte al formato pre definido (IWebviewMessage) para poder ser consumido del otro lado de la comunicación.

Se le debe indicar desde que aplicación se consume, mobile o web, para que realice un parseo u otro según el origen.

Ejemplo de implementación:

const decodeMessage = parseWebviewMessage({ message, appType: "web" });