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:
kind | Qué lleva | Cómo renderizarlo |
|---|---|---|
'native' | title, body, imageUrl, buttons | Componentes de React Native: <Text>, <Image>, <Pressable> |
'html' | html, css | Un 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ón | Tipo | Predeterminado | Descripción |
|---|---|---|---|
enableDebug | boolean | false | Activa el registro de depuración |
logLevel | cadena | 'info' | Nivel de registro: debug, info, warn, error |
batchSize | número | 50 | Eventos por lote antes del vaciado automático (predeterminado nativo) |
flushInterval | número | 5000 | Intervalo de vaciado automático en ms (predeterminado nativo) |
sessionTimeout | número | 1800000 | Tiempo de espera de sesión en ms (predeterminado nativo: 30 min) |
trackSessionStart | boolean | true | Rastrea automáticamente los eventos de inicio de sesión |
userId | cadena | null | ID 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';