Inizia

React Native ed Expo

@unolink/react-native è un sottile ponte sugli SDK nativi per iOS e Android, inclusi nel pacchetto. Non richiede alcun config plugin, nessun permesso oltre a internet e nessuna voce in Info.plist. Dal piano Pro in su.

Requisiti

  • React Native 0.79+ (nuova architettura).
  • Expo: una development build, npx expo prebuild o EAS Build. Non funziona in Expo Go, perché contiene codice nativo.
  • Una chiave SDK: nella dashboard, apri la tua app → Impostazioni → Chiavi SDK → Nuova chiave. Viene mostrata una sola volta, quindi copiala subito.

Installazione

Expo:

npx expo install @unolink/react-native
npx expo prebuild        # or: eas build

React Native senza Expo:

npm install @unolink/react-native
cd ios && pod install

Poi ricompila l’app. Ricaricare il JavaScript non basta dopo aver aggiunto codice nativo.

Se pod install fallisce con un errore di codifica (Ruby 4, o un locale che non è UTF-8), eseguilo in UTF-8:

cd ios && LANG=en_US.UTF-8 pod install

Non installare con npm install --legacy-peer-deps: riscrive package-lock.json e toglie le dipendenze peer opzionali.

Configurazione

Chiama configure una sola volta, al livello più alto, prima che venga mostrata la prima schermata: in app/_layout.tsx con Expo Router, oppure in index.js.

import { Unolink } from "@unolink/react-native"

Unolink.configure("ulk_…", { debug: __DEV__ })

Con la 0.3.1 o successiva:

  • Le chiamate fatte prima di configure aspettano, e vengono inviate subito dopo, quindi va bene ripristinare prima una sessione.
  • Una chiave mancante (per esempio una voce .env mancante) viene segnalata nella console invece di fallire in silenzio. Unolink.isConfigured() indica se è in funzione.
  • debug vale __DEV__ per impostazione predefinita.

Opzioni

OpzionePredefinitoCosa fa
debug__DEV__ (0.3.1+; false prima)Segna questa installazione come dispositivo di test. Le dashboard nascondono i dispositivi di test a meno che Includi dispositivi di test non sia attivo.
logLevel"warn"Quanto viene scritto nella console di Xcode o in Logcat (tag Unolink): "none", "error", "warn", "info", "debug".
baseUrlhttps://api.unolink.devL’API dell’SDK. Lasciala com’è.

La chiave è pubblica: viene distribuita dentro la tua app e può solo riportare dati per quell’unica app. Vedi Chiavi SDK.

Eventi del funnel

Aggiungi una riga in ogni momento importante. Diventano i passaggi in Funnel e Percorsi.

Unolink.onboardingCompleted()            // the last onboarding screen is done
Unolink.paywallViewed("onboarding")      // a paywall appeared; placement says which one
Unolink.paywallSkipped("onboarding")     // closed without buying
Unolink.signUp("apple")                  // a new account was created
Unolink.signIn("apple")                  // signed in to an account they already had
Unolink.signUpSkipped()                  // went on as a guest (0.3.1+)

Schermate di onboarding, una chiamata per schermata quando appare:

import { useOnboardingStep } from "@unolink/react-native"

useOnboardingStep("goal", { index: 0 })   // in each onboarding screen component
Unolink.onboardingSkipped("goal")         // on Skip

Gli ID delle schermate usano lettere, cifre, _ e . (how_heard, non how-heard). In sviluppo, lo StrictMode di React monta le schermate due volte, quindi lì potresti vedere una schermata inviata due volte; le build di release la inviano una volta. Le development build avvisano nella console di ID o proprietà che il server rifiuterebbe (0.3.1+).

Senza RevenueCat, riporta tu prove e acquisti. Passa l’importo come stringa, così non viene mai arrotondato:

Unolink.trialStarted("pro_yearly")
Unolink.purchase("49.99", "USD", "pro_yearly")
Unolink.purchaseCancelled("pro_yearly")               // closed the purchase sheet
Unolink.purchaseFailed("pro_yearly", "payment_failed")

I tuoi eventi accettano un nome e fino a 20 proprietà (stringhe, numeri o booleani):

Unolink.track("level_up", { level: 3 })

L’elenco completo, con i nomi che arrivano alla dashboard, è in Eventi.

ID utente e RevenueCat

Se usi RevenueCat, collegalo dalla tua app → Impostazioni → RevenueCat. Poi non chiamare purchase né trialStarted: RevenueCat invia da solo prove, acquisti, rinnovi, cancellazioni e rimborsi, e Unolink ignora le chiamate di acquisto dell’app, così nulla conta due volte.

Per collegare quegli acquisti all’installazione, riporta l’app user ID di RevenueCat. Con l’SDK 0.3.2 o successivo, una riga lo tiene aggiornato. Chiamala una volta all’avvio, prima o dopo configure:

import Purchases from "react-native-purchases"

Unolink.connectRevenueCat(Purchases)

Unolink legge l’ID subito, a ogni aggiornamento delle informazioni del cliente (acquisti, logIn, logOut) e ogni volta che l’app torna in primo piano, e lo invia solo quando è cambiato. Se RevenueCat non è ancora configurato, la lettura fallisce senza errori e viene ritentata più tardi. Restituisce una funzione che scollega. Per questo Unolink.revenueCatUserChanged() di solito non serve su React Native.

Senza di esso (o prima della 0.3.2), chiama setUserId con l’ID di RevenueCat dopo Purchases.configure, dopo ogni Purchases.logIn e Purchases.logOut, e a ogni avvio. Usa l’uno o l’altro, non entrambi:

// after Purchases.configure, logIn and logOut, and on every launch
Unolink.setUserId(await Purchases.getAppUserID())

Per un ospite, è l’ID anonimo di RevenueCat, quindi un acquisto fatto prima della registrazione si collega subito all’installazione. Dopo logIn, è l’ID dell’account. Ogni ID riportato da un’installazione conta, così l’acquisto dell’ospite resta collegato. Vedi Ospiti e account.

Unolink non salva mai l’ID in sé, solo un hash unidirezionale diverso per ciascuna delle tue app.

Su Android, quando qualcuno installa da un link Unolink che ha un deep link, il link arriva una volta, alla prima apertura. Su iPhone non arriva: Apple non ha un install referrer, e Unolink non usa mai il fingerprinting.

link.deepLink è quello che hai impostato sul link: un path come /promo/3for2, o un URL completo.

Le prime aperture di solito iniziano dall’onboarding. Se la schermata del link si trova dopo l’onboarding o l’accesso, aprilo quando sono finiti e poi segnalo come consumato (0.3.1+):

// when onboarding (or sign-in) is done, and on every launch after that until it's consumed:
const link = Unolink.getPendingDeferredDeepLink()
if (link?.deepLink) {
  router.push(link.deepLink)               // a path; open a full URL with Linking.openURL
  Unolink.consumeDeferredDeepLink()
}

Dalla 0.3.3 il link aspetta finché non lo consumi, anche se nel frattempo l’app viene chiusa (fino a 30 giorni dopo l’installazione). Un nuovo utente che esce a metà onboarding lo riceve comunque all’avvio successivo, quindi non devi salvarlo tu (niente AsyncStorage). Chiama consumeDeferredDeepLink() dopo averlo aperto: fino ad allora, getPendingDeferredDeepLink() lo restituisce a ogni avvio. È null prima di configure e finché Google Play non ha risposto. Con la 0.3.1 e la 0.3.2 viene conservato solo per l’avvio corrente.

Se la schermata è raggiungibile subito, basta un listener. I listener vengono chiamati una volta per installazione. Con la 0.3.1, un link arrivato prima della tua iscrizione va al primo listener che aggiungi; con la 0.3.0, iscriviti subito dopo configure.

import { router } from "expo-router"

const subscription = Unolink.addDeferredDeepLinkListener((link) => {
  // link.deepLink: "/promo/3for2", link.params: { offer: "3for2" }
  // link.linkSlug: "tiktok" or null, link.clickId: "clk_01JA…"
  if (link.deepLink) router.push(link.deepLink)
  Unolink.consumeDeferredDeepLink()
})

// when the component unmounts
subscription.remove()

Imposta Deep link e Parametri del link nella dashboard (Link → ⋯ → Modifica). Come funziona è spiegato in Deep link differiti su Android.

Altre chiamate

ChiamataCosa fa
Unolink.getInstallId()L’ID casuale di questa installazione, oppure null prima di configure. Non identifica nessuna persona né dispositivo.
Unolink.flush()Invia subito gli eventi in coda. Di solito non serve.
Unolink.setEnabled(false)Disattiva il tracciamento ed elimina gli eventi in coda, per la tua impostazione di opt-out. Viene ricordato tra un avvio e l’altro.

Le chiamate non lanciano mai eccezioni e non bloccano mai: gli eventi vengono messi in coda sul dispositivo e inviati in background dall’SDK nativo.

Jest

Dalla 0.3.1 il pacchetto ha il suo mock, che registra ogni chiamata:

jest.mock("@unolink/react-native", () => require("@unolink/react-native/jest"))
// expect(Unolink.signUp).toHaveBeenCalledWith("apple")

Dispositivi di test

Le development build sono dispositivi di test (passa debug: __DEV__ prima della 0.3.1). I canali di test di Google Play non possono essere riconosciuti sul telefono: passa debug: true in quelle build, per esempio da una variabile EXPO_PUBLIC_. I loro dati sono reali ma nascosti finché non attivi Includi dispositivi di test in Funnel e Percorsi. Altro in Test.

Privacy

  • Nessun IDFA, nessun Google Advertising ID, nessuna richiesta di App Tracking Transparency, nessun fingerprinting.
  • Un ID di installazione casuale, versione dell’app, versione del sistema operativo, versione dell’SDK, telefono o tablet, lingua. Il paese deriva dall’edge di rete. Gli indirizzi IP non vengono mai salvati.
  • Su iOS il privacy manifest dell’SDK nativo è incluso nel pacchetto: analytics, non collegati all’identità.
  • Non mettere mai nomi, email o altri dati personali nelle proprietà degli eventi.

Risoluzione dei problemi

  • "Native module not found" o simile? Sei in Expo Go, oppure non hai ricompilato dopo l’installazione. Crea una development build. Dalla 0.3.1 l’app non va in crash senza il modulo nativo: le chiamate non fanno nulla e un avviso spiega perché.
  • Niente nella dashboard? Attiva Includi dispositivi di test: le build __DEV__ sono nascoste per impostazione predefinita.
  • Ancora niente? Configura con { debug: __DEV__, logLevel: "debug" } e cerca Unolink nella console di Xcode o in Logcat. Una chiave sbagliata o revocata viene registrata come errore.

Altro in Risoluzione dei problemi.