React Native en Expo

@unolink/react-native is een dunne brug naar de native SDK's voor iOS en Android, die in het pakket zitten. Er is geen config plugin nodig, geen andere permissies dan internet en geen Info.plist-items. Pro-abonnement en hoger.

Vereisten

  • React Native 0.79+ (nieuwe architectuur).
  • Expo: een development build, npx expo prebuild of EAS Build. Het draait niet in Expo Go, omdat het native code bevat.
  • Een SDK-sleutel: open in het dashboard je app → Instellingen → SDK-sleutels → Nieuwe sleutel. Hij wordt maar één keer getoond, dus kopieer hem meteen.

Installeren

Expo:

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

Kale React Native:

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

Bouw de app daarna opnieuw. Een JavaScript-reload is niet genoeg nadat je native code hebt toegevoegd.

Faalt pod install met een coderingsfout (Ruby 4, of een locale die niet UTF-8 is), voer het dan uit in UTF-8:

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

Installeer niet met npm install --legacy-peer-deps: dat herschrijft package-lock.json en laat optionele peer-dependencies weg.

Configureren

Roep configure één keer aan, op het hoogste niveau, voordat je eerste scherm rendert: in app/_layout.tsx met Expo Router, of in index.js.

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

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

Met 0.3.1 of hoger:

  • Aanroepen vóór configure wachten, en worden direct daarna verstuurd, dus eerst een sessie herstellen is geen probleem.
  • Een ontbrekende sleutel (bijvoorbeeld een ontbrekend item in .env) wordt in de console gemeld in plaats van stilletjes te mislukken. Unolink.isConfigured() zegt of de SDK draait.
  • debug is standaard __DEV__.

Opties

OptieStandaardWat het doet
debug__DEV__ (0.3.1+; daarvoor false)Markeert deze installatie als testapparaat. Dashboards verbergen testapparaten, tenzij Testapparaten meetellen aan staat.
logLevel"warn"Hoeveel er naar de Xcode-console of Logcat gaat (tag Unolink): "none", "error", "warn", "info", "debug".
baseUrlhttps://api.unolink.devDe SDK-API. Laat hem zoals hij is.

De sleutel is openbaar: hij zit in je app en kan alleen gegevens voor die ene app melden. Zie SDK-sleutels.

Funnelevents

Voeg één regel toe op elk moment dat ertoe doet. Dit worden de stappen in Funnel en Trajecten.

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+)

Onboardingschermen, één aanroep per scherm zodra het verschijnt:

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

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

Scherm-ID's gebruiken letters, cijfers, _ en . (how_heard, niet how-heard). Tijdens het ontwikkelen mount StrictMode van React schermen twee keer, dus daar kun je een scherm twee keer verstuurd zien; releasebuilds versturen het één keer. Development builds waarschuwen in de console voor ID's of eigenschappen die de server zou weigeren (0.3.1+).

Zonder RevenueCat meld je proefperiodes en aankopen zelf. Geef het bedrag mee als string, zodat het nooit wordt afgerond:

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")

Je eigen events krijgen een naam en tot 20 eigenschappen (strings, getallen of booleans):

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

De volledige lijst, met de namen die in het dashboard aankomen, staat in Events.

Gebruikers-ID en RevenueCat

Gebruik je RevenueCat, verbind het dan onder je app → Instellingen → RevenueCat. Roep daarna geen purchase of trialStarted aan: RevenueCat verstuurt zelf proefperiodes, aankopen, verlengingen, opzeggingen en terugbetalingen, en Unolink negeert aankoopaanroepen vanuit de app, zodat niets dubbel telt.

Om die aankopen aan de installatie te koppelen, meld je de eigen app-gebruikers-ID van RevenueCat. Met SDK 0.3.2 of nieuwer houdt één regel die actueel. Roep hem één keer aan bij de start, vóór of na configure:

import Purchases from "react-native-purchases"

Unolink.connectRevenueCat(Purchases)

Unolink leest de ID meteen, bij elke update van de klantinfo (aankopen, logIn, logOut) en telkens wanneer de app terugkomt naar de voorgrond, en verstuurt hem alleen als hij is veranderd. Is RevenueCat nog niet geconfigureerd, dan mislukt het lezen stil en wordt het later opnieuw geprobeerd. Het geeft een functie terug die de verbinding verbreekt. Unolink.revenueCatUserChanged() is op React Native dus normaal niet nodig.

Zonder dit (of vóór 0.3.2) roep je setUserId aan met de ID van RevenueCat na Purchases.configure, na elke Purchases.logIn en Purchases.logOut, en bij elke start. Gebruik het een of het ander, niet allebei:

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

Voor een gast is dat het anonieme ID van RevenueCat, dus een aankoop die vóór de aanmelding wordt gedaan, wordt meteen aan de installatie gekoppeld. Na logIn is het de ID van het account. Elke ID die een installatie heeft gemeld telt mee, dus de aankoop van de gast blijft gekoppeld. Zie Gasten en accounts.

Unolink slaat de ID zelf nooit op, alleen een eenrichtingshash die voor elk van je apps anders is.

Als iemand op Android installeert via een Unolink-link met een deeplink, komt de link één keer binnen, bij de eerste keer openen. Op iPhone is er geen: Apple heeft geen install referrer, en Unolink gebruikt nooit fingerprinting.

link.deepLink is wat je bij de link hebt ingesteld: een pad zoals /promo/3for2, of een volledige URL.

De eerste keer openen begint meestal met de onboarding. Zit het scherm van de link achter de onboarding of het inloggen, open hem dan zodra dat klaar is en markeer hem daarna als gebruikt (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()
}

Vanaf 0.3.3 wacht de link tot je hem als gebruikt markeert, ook als de app intussen wordt gesloten (tot 30 dagen na de installatie). Een nieuwe gebruiker die halverwege de onboarding stopt, krijgt hem bij de volgende start toch, dus je hoeft hem niet zelf op te slaan (geen eigen AsyncStorage). Roep consumeDeferredDeepLink() aan zodra je hem hebt geopend: tot dan geeft getPendingDeferredDeepLink() hem bij elke start terug. Vóór configure en tot Google Play heeft geantwoord is hij null. Met 0.3.1 en 0.3.2 blijft hij alleen bewaard voor de huidige start van de app.

Is het scherm meteen bereikbaar, dan is een listener genoeg. Listeners worden één keer per installatie aangeroepen. Met 0.3.1 gaat een link die binnenkwam voordat je je abonneerde naar de eerste listener die je toevoegt; met 0.3.0 abonneer je je direct na 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()

Stel de Deeplink en Parameters van de link in het dashboard in (Links → ⋯ → Bewerken). Hoe het werkt, staat in Uitgestelde deep links op Android.

Andere aanroepen

AanroepWat het doet
Unolink.getInstallId()De willekeurige ID van deze installatie, of null vóór configure. Hij identificeert geen persoon of apparaat.
Unolink.flush()Verstuurt events uit de wachtrij meteen. Normaal niet nodig.
Unolink.setEnabled(false)Zet tracking uit en verwijdert events uit de wachtrij, voor je opt-outinstelling. Blijft bewaard tussen starts.

Aanroepen gooien nooit een fout en blokkeren nooit: events worden op het apparaat in een wachtrij gezet en op de achtergrond verstuurd door de native SDK.

Jest

Vanaf 0.3.1 heeft het pakket een eigen mock, die elke aanroep vastlegt:

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

Testapparaten

Development builds zijn testapparaten (geef vóór 0.3.1 debug: __DEV__ mee). Testtracks van Google Play zijn op de telefoon niet te herkennen: geef in die builds debug: true mee, bijvoorbeeld via een EXPO_PUBLIC_-variabele. Hun gegevens zijn echt, maar verborgen tot je Testapparaten meetellen aanzet in Funnel en Trajecten. Meer in Testen.

Privacy

  • Geen IDFA, geen Google Advertising ID, geen App Tracking Transparency-melding, geen fingerprinting.
  • Een willekeurige installatie-ID, appversie, OS-versie, SDK-versie, telefoon of tablet, taal. Het land komt van de netwerkrand. IP-adressen worden nooit opgeslagen.
  • Op iOS zit het privacymanifest van de native SDK in het pakket: analyse, niet gekoppeld aan identiteit.
  • Zet nooit namen, e-mailadressen of andere persoonsgegevens in eigenschappen van events.

Problemen oplossen

  • "Native module not found" of iets vergelijkbaars? Je zit in Expo Go, of je hebt niet opnieuw gebouwd sinds de installatie. Maak een development build. Vanaf 0.3.1 crasht de app niet zonder de native module: aanroepen doen niets en een waarschuwing legt uit waarom.
  • Niets in het dashboard? Zet Testapparaten meetellen aan: __DEV__-builds zijn standaard verborgen.
  • Nog steeds niets? Configureer met { debug: __DEV__, logLevel: "debug" } en zoek naar Unolink in de Xcode-console of Logcat. Een verkeerde of ingetrokken sleutel wordt als fout gelogd.

Meer in Problemen oplossen.