דלג לתוכן הראשי

שילוב React Native SDK

עטיפת React Native שמגשרת בין ערכות ה-SDK הנייטיביות של iOS ו-Android, ומספקת API יחיד ב-TypeScript עם כל יכולות הפלטפורמה.

יכולות

  • גשר נייטיבי - עוטף את ערכות ה-SDK הנייטיביות של iOS (Swift) ו-Android (Kotlin)
  • מעקב אירועים - מעקב אירועים מותאמים וצפיות במסך
  • זיהוי משתמשים - זיהוי, קישור וניהול מאפייני משתמש
  • התראות פוש - רישום טוקנים, מעקב אחר לחיצות (FCM + APNs)
  • הודעות In-App - קבלה והצגת הודעות בתוך האפליקציה
  • מסחר אלקטרוני - מעקב רכישות, עגלה, תשלום
  • תמיכה במצב לא מקוון - אירועים נשמרים מקומית ומסונכרנים כשיש חיבור
  • ניסיונות חוזרים - השהיה מעריכית בין ניסיונות לאחר כשל ברשת

דרישות

  • React Native 0.72+
  • iOS 14.0+ / Android SDK 24+
  • TypeScript 5.0+ (מומלץ)

התקנה

npm install @joryio/react-native-sdk

הגדרת iOS

cd ios && pod install

הגדרת Android

הוסיפו את החבילה ב-MainApplication.kt:

import io.joryio.reactnative.JoryioPackage

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

התחלה מהירה

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

// אתחול פעם אחת ב-App.tsx
await Joryio.initialize(
'jry_sdk_ios_your_key', // מפתח ה-SDK שלכם
'api-eu1.joryio.com', // מארח ה-API (שם מארח בלבד, ללא סכמה)
{
enableDebug: __DEV__,
trackSessionStart: true,
}
);

מעקב אירועים

מעקב אירועים מותאמים

// אירוע בסיסי
Joryio.track('Button Clicked');

// אירוע עם מאפיינים
Joryio.track('Product Added', {
productId: 'SKU-123',
productName: 'חולצה כחולה',
price: 29.99,
currency: 'ILS',
});

// אירועי מסחר אלקטרוני
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: 'ILS',
});

מעקב צפיות במסך

Joryio.trackScreen('ProductDetail', { productId: 'SKU-123' });
Joryio.trackScreen('Cart');
Joryio.trackScreen('Checkout');

שילוב עם 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>
);
}

זיהוי משתמשים

זיהוי לאחר התחברות

// לאחר login
Joryio.identify('user-123');

// עם מאפיינים
Joryio.identify('user-123');
Joryio.setAttributes({
email: 'john@example.com',
firstName: 'John',
plan: 'premium',
});

קישור משתמש אנונימי (Alias)

קישור פעילות אנונימית למשתמש מזוהה (למשל לאחר הרשמה):

Joryio.alias('user-123');

איפוס (התנתקות)

ניקוי זהות המשתמש והתחלת סשן אנונימי חדש:

Joryio.reset();

מאפייני משתמש

// הגדרת מספר מאפיינים
Joryio.setAttributes({
firstName: 'ישראל',
lastName: 'ישראלי',
plan: 'premium',
age: 28,
isVIP: true,
});

// הגדרת מאפיין יחיד
Joryio.setAttribute('favoriteColor', 'blue');

// הגדלת ערך מספרי
Joryio.incrementAttribute('loginCount', 1);
Joryio.incrementAttribute('totalSpent', 29.99);

// הסרת מאפיין
Joryio.unsetAttribute('temporaryFlag');

התראות פוש

הגדרה עם Firebase

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

// בקשת הרשאה
const authStatus = await messaging().requestPermission();

// קבלת ורישום טוקן
const token = await messaging().getToken();
Joryio.registerPushToken(token);

// מעקב אחר רענון טוקן
messaging().onTokenRefresh((newToken) => {
Joryio.registerPushToken(newToken);
});

טיפול בלחיצה על התראה

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

// כשהאפליקציה ברקע והמשתמש לוחץ על ההתראה
messaging().onNotificationOpenedApp((remoteMessage) => {
const trackingId = remoteMessage.data?.joryio_tracking_id;
if (trackingId) {
Joryio.trackPushClick(trackingId);
}
});

// כשהאפליקציה הייתה סגורה ונפתחה דרך ההתראה
messaging()
.getInitialNotification()
.then((remoteMessage) => {
if (remoteMessage?.data?.joryio_tracking_id) {
Joryio.trackPushClick(remoteMessage.data.joryio_tracking_id);
}
});

בדיקת סטטוס פוש

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

הודעות In-App

ההודעות מוצגות מעצמן. התקינו את ה־SDK, שלחו קמפיין, והוא יופיע - מצויר על ידי ה־View־ים הטבעיים, עם הגופנים, הצבעים והמצב הכהה של האפליקציה שלכם. אין מה לחבר.

שאר הסעיף הזה נחוץ רק אם ברצונכם להציג את ההודעות ב־React במקום - ראו השתלטות על הרינדור.

אסימוני שליחה (delivery tokens)

כאשר השרת מגיש קמפיין מתאים, הוא מנפיק עבורו גם אסימון שליחה חתום וקצר-מועד. ה-SDK מחזיר את האסימון כשהוא מדווח על הצגה, קליק או סגירה, והשרת מאמת את החתימה לפני שהוא רושם משהו.

אינך צריך לעשות דבר - ה-SDK מטפל בזה עבורך. התיעוד כאן נועד להסביר מה קורה ללקוח שאינו שולח אסימון:

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

האסימון הוא מה שהופך דיווח הצגה לאמין: בלעדיו, כל מי שמחזיק במפתח ה-SDK - שנשלח בתוך כל אפליקציה ובכל עמוד - היה יכול לדווח על הצגות וקליקים לקמפיין שמעולם לא הוצג, והדוחות שלך היו סופרים אותם.

אם הצגות in-app מפסיקות להירשם, ודא שהאפליקציה נבנתה מול גרסה עדכנית של ה-SDK: בנייה שנעשתה לפני שאסימוני השליחה נוספו אינה שולחת אסימון, והשרת ידחה את ההצגות שלה.

שני סוגי תוכן

לכל הודעה יש שדה kind שמציין את צורת התוכן. פצלו לפיו:

kindמה הוא נושאאיך להציג
'native'title, body, imageUrl, buttonsרכיבי React Native - <Text>, <Image>, <Pressable>
'html'html, cssWebView

השתלטות על הרינדור

הרשמה עם onInAppMessage מפסיקה את הציור של ה־SDK ומעבירה כל הודעה לקוד שלכם, כדי שתציגו אותה עם רכיבי React Native. לא תקבלו שני עותקים.

עשו זאת אם אתם רוצים שההודעות יתאימו לשאר הממשק שלכם, או אם אסור לאפליקציה לקשר WebView - ובמקרה הזה גם החריגו את artifact ה־UI מה־build (joryio-android-ui באנדרואיד, ה־product בשם JoryioUI ב־iOS).

האזנה להודעות

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} />}</>;
}

הצגת הודעת Native

תוכן Native הוא טקסט, לא markup. הכניסו אותו ל־<Text> - העברתו ל־WebView או ל־dangerouslySetInnerHTML תחזיר בדיוק את סיכון ההזרקה ש־Native נועד למנוע.

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}` }} />;
}

החלת ה-Style של הקמפיין

השדה message.style נושא את הדריסות שמחבר הקמפיין הגדיר. כל שדה אופציונלי, ושדה חסר משמעו ירושה מהמראה של האפליקציה שלכם - לכן החילו רק את מה שקיים, ואל תחליפו בברירות מחדל משלכם:

const st = message.style;
const text = {
// 'auto' מיישר לפי שפת ההודעה, לא לפי שפת המכשיר -
// I18nManager.isRTL הוא הבדיקה הלא נכונה כשאותו workspace שולח עברית ואנגלית
// לאותה אפליקציה.
writingDirection: 'auto' as const,
textAlign: st?.textAlign === 'center' ? 'center' : 'auto',
...(st?.fontFamily ? { fontFamily: st.fontFamily } : {}),
};

החילו fontFamily רק אם האפליקציה שלכם ארזה את הגופן; עדיף להישאר עם הגופן שלכם מאשר להחליף בגופן אקראי. אם הקמפיין הגדיר צבע כפתור בלי צבע טקסט, בחרו שחור או לבן לפי הניגודיות מול הצבע - ברירת מחדל לבנה הופכת צבע מותג בהיר לבלתי נראה.

הפעלת הודעות HTML

הודעות HTML כבויות כברירת מחדל. הודעת HTML מריצה JavaScript שנכתב על ידי המחבר בתוך האפליקציה שלכם, ולכן ההפעלה היא החלטה של צוות האפליקציה - לא משהו שמפעילים ממערכת השיווק:

await Joryio.initialize('jry_sdk_YOUR_KEY', 'api-eu1.joryio.com', {
allowHtmlJsInAppMessages: true, // ברירת מחדל: false
});

השארת ההגדרה כבויה אינה מבטלת הודעות In-App - הודעות Native ימשיכו להגיע. רק קמפייני HTML מדולגים.

מעקב אחר חשיפות

// כשהודעה מוצגת
Joryio.trackInAppImpression(message.id, 'displayed');

// כשהמשתמש לוחץ
Joryio.trackInAppImpression(message.id, 'clicked');

// כשהמשתמש סוגר
Joryio.trackInAppImpression(message.id, 'dismissed');

אפשרויות הגדרה

אפשרותסוגברירת מחדלתיאור
enableDebugbooleanfalseהפעלת יומני ניפוי שגיאות
logLevelstring'info'רמת לוג: debug, info, warn, error
batchSizenumber50אירועים לאצווה לפני שליחה אוטומטית (ברירת מחדל נייטיב)
flushIntervalnumber5000מרווח שליחה אוטומטית במילישניות (ברירת מחדל נייטיב)
sessionTimeoutnumber1800000פסק זמן של סשן במילישניות (ברירת מחדל נייטיב: 30 דקות)
trackSessionStartbooleantrueמעקב אוטומטי אחר תחילת סשן
userIdstringnullהגדרת מזהה משתמש מראש

כלי עזר

// שליחת אירועים מיידית (לפני סגירת אפליקציה, התנתקות וכו')
Joryio.flush();

// קבלת מזהים
const anonymousId = await Joryio.getAnonymousId();
const userId = await Joryio.getUserId(); // null אם לא מזוהה
const sessionId = await Joryio.getSessionId();

תמיכת TypeScript

ה-SDK כולל טיפוסים מלאים. ייבאו לפי הצורך:

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