Saltar al contenido principal

Integración del SDK de React Native

Envoltorio de React Native que conecta los SDK nativos de iOS y Android y ofrece todas las capacidades de la plataforma mediante una única API de TypeScript.

Funciones

  • Puente nativo: envuelve los SDK nativos de iOS (Swift) y Android (Kotlin).
  • Rastreo de eventos: registra eventos personalizados y vistas de pantalla.
  • Identidad de usuario: identifica, asigna alias y gestiona atributos de usuario.
  • Notificaciones push: registra tokens y rastrea clics (FCM y APNs).
  • Mensajería in-app: recibe y muestra mensajes in-app.
  • E-commerce: rastrea compras, eventos del carrito y checkout.
  • Compatibilidad sin conexión: los eventos se encolan localmente y se sincronizan al volver a estar en línea.
  • Reintento automático: espera exponencial ante fallos de red.

Requisitos

  • React Native 0.72+
  • iOS 14.0+ / Android SDK 24+
  • TypeScript 5.0+ (recomendado)

Instalación

npm install @joryio/react-native-sdk

Configuración de iOS

cd ios && pod install

Configuración de Android

Añade el paquete de Joryio a MainApplication.kt:

import io.joryio.reactnative.JoryioPackage

override fun getPackages() = PackageList(this).packages.apply {
add(JoryioPackage())
}

Inicio rápido

import Joryio from '@joryio/react-native-sdk';

// Inicializa una vez en App.tsx
await Joryio.initialize(
'jry_sdk_ios_your_key', // Tu clave de SDK
'api-eu1.joryio.com', // Host de la API (solo nombre de host, sin esquema)
{
enableDebug: __DEV__,
trackSessionStart: true,
}
);

Rastreo de eventos

Rastrear eventos personalizados

// Evento básico
Joryio.track('Button Clicked');

// Evento con propiedades
Joryio.track('Product Added', {
productId: 'SKU-123',
productName: 'Blue T-Shirt',
price: 29.99,
currency: 'USD',
});

// Eventos de e-commerce
Joryio.track('Checkout Started', {
value: 89.97,
items: [
{ productId: 'SKU-123', quantity: 2, price: 29.99 },
{ productId: 'SKU-456', quantity: 1, price: 29.99 },
],
});

Joryio.track('Order Completed', {
order_id: 'ORD-789',
value: 89.97,
currency: 'USD',
});

Rastrear vistas de pantalla

// En los componentes de tus pantallas
Joryio.trackScreen('ProductDetail', { productId: 'SKU-123' });
Joryio.trackScreen('Cart');
Joryio.trackScreen('Checkout');

Integración con React Navigation

import { NavigationContainer } from '@react-navigation/native';

function App() {
const routeNameRef = useRef<string>();

return (
<NavigationContainer
onStateChange={() => {
const currentRouteName = navigationRef.current?.getCurrentRoute()?.name;
if (currentRouteName && currentRouteName !== routeNameRef.current) {
Joryio.trackScreen(currentRouteName);
routeNameRef.current = currentRouteName;
}
}}
>
{/* ... */}
</NavigationContainer>
);
}

Identidad de usuario

Identificar usuarios

Llama a identify después de iniciar sesión o cuando sepas quién es el usuario:

// Después de iniciar sesión
Joryio.identify('user-123');

// Con atributos
Joryio.identify('user-123');
Joryio.setAttributes({
email: 'john@example.com',
firstName: 'John',
plan: 'premium',
});

Asignar alias a usuarios

Vincula actividad anónima con un usuario conocido, por ejemplo tras registrarse:

Joryio.alias('user-123');

Restablecer (cerrar sesión)

Borra la identidad del usuario e inicia una sesión anónima nueva:

Joryio.reset();

Atributos de usuario

// Establece varios atributos
Joryio.setAttributes({
firstName: 'John',
lastName: 'Doe',
plan: 'premium',
age: 28,
isVIP: true,
});

// Establece un atributo
Joryio.setAttribute('favoriteColor', 'blue');

// Incrementa un atributo numérico
Joryio.incrementAttribute('loginCount', 1);
Joryio.incrementAttribute('totalSpent', 29.99);

// Elimina un atributo
Joryio.unsetAttribute('temporaryFlag');

Notificaciones push

Configuración con Firebase (React Native Firebase)

import messaging from '@react-native-firebase/messaging';

// Solicita permiso
const authStatus = await messaging().requestPermission();

// Obtén y registra el token
const token = await messaging().getToken();
Joryio.registerPushToken(token);

// Escucha la actualización del token
messaging().onTokenRefresh((newToken) => {
Joryio.registerPushToken(newToken);
});

Gestionar clics en notificaciones push

import messaging from '@react-native-firebase/messaging';

// Cuando la aplicación está en segundo plano y se toca la notificación
messaging().onNotificationOpenedApp((remoteMessage) => {
const trackingId = remoteMessage.data?.joryio_tracking_id;
if (trackingId) {
Joryio.trackPushClick(trackingId);
}
});

// Cuando la aplicación estaba cerrada y se abre desde una notificación
messaging()
.getInitialNotification()
.then((remoteMessage) => {
if (remoteMessage?.data?.joryio_tracking_id) {
Joryio.trackPushClick(remoteMessage.data.joryio_tracking_id);
}
});

Comprobar el estado de push

const enabled = await Joryio.isPushEnabled();
console.log('Push enabled:', enabled);

Mensajería in-app

Los mensajes se muestran solos. Instala el SDK, envía una campaña y aparece, dibujada por las vistas nativas con las fuentes, los colores y el modo oscuro de tu app. No hay nada que conectar.

Solo necesitas el resto de esta sección si prefieres renderizar los mensajes en React; consulta Encargarte tú del renderizado.

Tokens de entrega (delivery tokens)

Cuando el backend sirve una campaña elegible, emite también un token de entrega firmado y de corta duración. El SDK lo devuelve al informar una impresión, un clic o un cierre, y el servidor verifica la firma antes de registrar nada.

No tienes que hacer nada: el SDK se encarga por ti. Se documenta porque cambia lo que ocurre con un cliente que no envía token:

POST /v1/in-app/track   (no deliveryToken)
{ "success": false, "error": "A delivery token is required" }

El token es lo que hace que una impresión sea fiable: sin él, cualquiera que tenga la SDK key - que viaja dentro de cada app y cada página - podría informar impresiones y clics de una campaña que nunca se mostró, y tus informes los contarían.

Si dejan de registrarse impresiones in-app, comprueba que la app esté compilada contra una versión actual del SDK: una compilación anterior a los tokens de entrega no envía token y el servidor rechazará sus impresiones.

Dos tipos de contenido

Cada mensaje lleva un kind que indica su forma. Ramifica según él:

kindQué llevaCómo renderizarlo
'native'title, body, imageUrl, buttonsComponentes de React Native: <Text>, <Image>, <Pressable>
'html'html, cssUn WebView

Encargarte tú del renderizado

Suscribirte con onInAppMessage detiene el dibujado del SDK y entrega cada mensaje a tu código, para que lo renderices con componentes de React Native. No recibirás dos copias.

Hazlo si quieres que los mensajes in-app encajen con el resto de tu interfaz, o si tu app no debe enlazar un web view; en ese caso excluye además el artefacto de UI de tu build (joryio-android-ui en Android, el producto JoryioUI en iOS).

Escuchar mensajes

import { useEffect, useState } from 'react';
import Joryio, { type InAppMessage } from '@joryio/react-native';

function App() {
const [message, setMessage] = useState<InAppMessage | null>(null);

useEffect(() => Joryio.onInAppMessage(setMessage), []);

return <>{message && <InAppMessageHost message={message} />}</>;
}

Renderizar un mensaje nativo

El contenido nativo es texto, no marcado. Ponlo en un <Text>: pasarlo a un WebView o a dangerouslySetInnerHTML reintroduciría exactamente el riesgo de inyección que lo nativo evita.

function InAppMessageHost({ message }: { message: InAppMessage }) {
if (message.kind === 'native') {
return (
<View>
{message.imageUrl && <Image source={{ uri: message.imageUrl }} />}
{message.title && <Text style={styles.title}>{message.title}</Text>}
<Text>{message.body}</Text>

{message.buttons.map((button) => (
<Pressable
key={button.id}
onPress={() => {
if (button.action === 'url' && button.url) Linking.openURL(button.url);
Joryio.trackInAppImpression(message.id, 'clicked');
}}
>
<Text>{button.text}</Text>
</Pressable>
))}
</View>
);
}

return <WebView source={{ html: `<style>${message.css}</style>${message.html}` }} />;
}

Aplica el estilo de la campaña

message.style lleva las anulaciones que fijó quien creó la campaña. Todos los campos son opcionales y uno ausente significa heredar el aspecto de tu propia aplicación: aplica solo lo que venga.

const st = message.style;
const text = {
// 'auto' alinea según el idioma del MENSAJE, no el del dispositivo.
writingDirection: 'auto' as const,
textAlign: st?.textAlign === 'center' ? 'center' : 'auto',
...(st?.fontFamily ? { fontFamily: st.fontFamily } : {}),
};

Aplica fontFamily solo si tu aplicación incluye esa fuente. Si la campaña fija un color de botón y ninguno de etiqueta, elige negro o blanco por contraste: el blanco por defecto hace invisible un relleno claro.

Permitir mensajes HTML

Los mensajes HTML están desactivados por defecto. Un mensaje HTML ejecuta JavaScript escrito por el autor dentro de tu app, así que activarlo es una decisión del equipo de la app:

await Joryio.initialize('jry_sdk_YOUR_KEY', 'api-eu1.joryio.com', {
allowHtmlJsInAppMessages: true, // por defecto: false
});

Dejarlo desactivado no desactiva la mensajería in-app: los mensajes nativos siguen llegando. Solo se omiten las campañas HTML.

Rastrear impresiones

// Cuando se muestra el mensaje
Joryio.trackInAppImpression(message.id, 'displayed');

// Cuando el usuario hace clic
Joryio.trackInAppImpression(message.id, 'clicked');

// Cuando el usuario lo descarta
Joryio.trackInAppImpression(message.id, 'dismissed');

Opciones de configuración

OpciónTipoPredeterminadoDescripción
enableDebugbooleanfalseActiva el registro de depuración
logLevelcadena'info'Nivel de registro: debug, info, warn, error
batchSizenúmero50Eventos por lote antes del vaciado automático (predeterminado nativo)
flushIntervalnúmero5000Intervalo de vaciado automático en ms (predeterminado nativo)
sessionTimeoutnúmero1800000Tiempo de espera de sesión en ms (predeterminado nativo: 30 min)
trackSessionStartbooleantrueRastrea automáticamente los eventos de inicio de sesión
userIdcadenanullID de usuario predefinido al inicializar

Utilidades

// Vacía los eventos de inmediato (antes de cerrar la aplicación, cerrar sesión, etc.)
Joryio.flush();

// Obtén los ID
const anonymousId = await Joryio.getAnonymousId();
const userId = await Joryio.getUserId(); // null si no se identificó
const sessionId = await Joryio.getSessionId();

Compatibilidad con TypeScript

El SDK está completamente tipado. Importa los tipos que necesites:

import Joryio, {
type JoryioConfig,
type UserAttributes,
type InAppMessage,
} from '@joryio/react-native-sdk';