Flutter

Le package unolink est une fine couche au-dessus des SDK natifs iOS et Android, qui sont fournis avec lui. Il ne demande aucune permission en dehors d’internet et aucune entrée Info.plist. Publié sur pub.dev par unolink.dev. Forfait Pro et plus.

Prérequis

  • Flutter 3.22+ (Dart 3.4+).
  • Android 6.0+ (minSdk 23) et iOS 13+.
  • Une clé SDK : dans le tableau de bord, ouvrez votre app → Paramètres → Clés SDK → Nouvelle clé. Elle n’est affichée qu’une fois, copiez-la à ce moment-là.

Installation

flutter pub add unolink

Cela ajoute unolink: ^0.3.3 à pubspec.yaml et le télécharge. Recompilez ensuite l’app ; un hot reload ne suffit pas après l’ajout de code natif.

Si CocoaPods échoue pendant le build iOS sur une erreur d’encodage (Ruby 4, ou une locale qui n’est pas en UTF-8), lancez-le vous-même en UTF-8, puis relancez le build :

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

Configuration

Appelez configure une seule fois dans main(), après WidgetsFlutterBinding.ensureInitialized() et avant runApp :

import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';
import 'package:unolink/unolink.dart';

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Unolink.configure('ulk_…', debug: kDebugMode);
  runApp(const MyApp());
}

Options

OptionPar défautCe qu’elle fait
debugfalseMarque cette installation comme appareil de test. Passez kDebugMode. Les tableaux de bord masquent les appareils de test sauf si Inclure les appareils de test est activé.
logLevelUnolinkLogLevel.warnLa quantité de logs envoyée vers la console Xcode ou Logcat (tag Unolink) : none, error, warn, info, debug.
baseUrlhttps://api.unolink.devL’API du SDK. Laissez-la telle quelle.

La clé est publique : elle est livrée dans votre app et ne peut envoyer des données que pour cette app. Voir Clés SDK.

Événements d’entonnoir

Ajoutez une ligne à chaque moment qui compte. Elles deviennent les étapes de Entonnoir et Parcours.

Unolink.onboardingCompleted();                     // the last onboarding screen is done
Unolink.paywallViewed(placement: 'onboarding');    // a paywall appeared; placement says which one
Unolink.paywallSkipped(placement: 'onboarding');   // closed without buying
Unolink.signUp(method: 'apple');                   // an account was created
Unolink.signUpSkipped();                           // went on as a guest (0.3.2+)

Sans RevenueCat, remontez vous-même les essais et les achats. Le montant est une chaîne, il n’est donc jamais arrondi :

Unolink.trialStarted(productId: 'pro_yearly');
Unolink.purchase('49.99', 'USD', productId: 'pro_yearly');
Unolink.purchaseCancelled(productId: 'pro_yearly');              // closed the purchase sheet
Unolink.purchaseFailed(productId: 'pro_yearly', reason: 'payment_failed');

Vos propres événements prennent un nom et jusqu’à 20 propriétés :

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

La liste complète, avec les noms qui arrivent dans le tableau de bord, se trouve dans Événements.

Identifiant utilisateur et RevenueCat

Si vous utilisez RevenueCat, connectez-le dans votre app → Paramètres → RevenueCat. N’appelez alors pas purchase ni trialStarted : RevenueCat envoie lui-même les essais, achats, renouvellements, annulations et remboursements, et Unolink ignore les appels d’achat de l’app pour que rien ne compte deux fois.

Pour relier ces achats à l’installation, signalez le propre identifiant utilisateur d’app de RevenueCat. Avec le SDK 0.3.2 ou plus récent, une seule ligne le tient à jour. Appelez-la une fois au lancement, avant ou après configure :

Unolink.connectRevenueCat(
  () => Purchases.appUserID,
  addListener: Purchases.addCustomerInfoUpdateListener,
  removeListener: Purchases.removeCustomerInfoUpdateListener,
);

Unolink lit l’identifiant une fois RevenueCat configuré, à chaque mise à jour des infos client (achats, logIn, logOut) et chaque fois que l’app reprend, et ne l’envoie que s’il a changé. Si RevenueCat n’est pas encore configuré, la lecture échoue sans bruit et est retentée plus tard. L’appel renvoie une fonction qui déconnecte. Unolink.revenueCatUserChanged() n’est donc normalement pas nécessaire sur Flutter.

Sans elle (ou avant la 0.3.2), appelez setUserId avec l’identifiant de RevenueCat après Purchases.configure, après chaque Purchases.logIn et Purchases.logOut, et à chaque lancement. Utilisez l’un ou l’autre, pas les deux :

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

Pour un invité, c’est l’identifiant anonyme de RevenueCat, donc un achat fait avant l’inscription est relié à l’installation tout de suite. Après logIn, c’est l’identifiant du compte. Chaque identifiant signalé par une installation compte, donc l’achat de l’invité reste relié. Voir Invités et comptes.

Unolink ne stocke jamais l’identifiant lui-même, seulement un hachage à sens unique, différent pour chacune de vos apps.

Sur Android, quand quelqu’un installe depuis un lien Unolink qui a un deep link, le listener s’exécute une fois, à la première ouverture. Sur iPhone, il n’est pas appelé : Apple n’a pas de referrer d’installation, et Unolink ne fait jamais de fingerprinting.

Unolink.setDeferredDeepLinkListener((link) {
  // link.deepLink: '/promo/3for2', link.params: {'offer': '3for2'}
  // link.linkSlug: 'tiktok' or null, link.clickId: 'clk_01JA…'
  if (link.deepLink != null) router.go(link.deepLink!);
  Unolink.consumeDeferredDeepLink();
});

Le listener est appelé une fois par installation. Un lien arrivé avant que vous le définissiez lui est transmis dès que vous le définissez.

L’ouvrir après l’onboarding

Les premières ouvertures commencent généralement par l’onboarding. Si l’écran du lien se trouve derrière l’onboarding ou la connexion, ne l’ouvrez pas depuis le listener. Une fois l’onboarding (ou la connexion) terminé, lisez le lien en attente, ouvrez-le, puis consommez-le :

// when onboarding (or sign-in) is done, and on every launch after that until it's consumed
final link = await Unolink.getPendingDeferredDeepLink();
if (link?.deepLink != null) {
  router.go(link!.deepLink!);
  await Unolink.consumeDeferredDeepLink();
}

Le lien attend que vous le consommiez, même si l’app est fermée entre-temps (jusqu’à 30 jours après l’installation ; 0.3.3+). Un nouvel utilisateur qui quitte l’app au milieu de l’onboarding le retrouve au lancement suivant : inutile de le stocker vous-même. Appelez consumeDeferredDeepLink() une fois que vous l’avez ouvert : d’ici là, getPendingDeferredDeepLink() le renvoie à chaque lancement. Il vaut null avant configure et tant que Google Play n’a pas répondu, et toujours null sur iPhone.

Définissez le Deep link et les Paramètres du lien dans le tableau de bord (Liens → ⋯ → Modifier). Le fonctionnement est expliqué dans Liens profonds différés Android.

Autres appels

AppelCe qu’il fait
await Unolink.getInstallId()L’identifiant d’installation aléatoire, ou null avant configure. Il n’identifie aucune personne ni aucun appareil.
Unolink.flush()Envoie tout de suite les événements en file d’attente. Normalement inutile.
Unolink.setEnabled(false)Désactive le suivi et supprime les événements en file d’attente, pour votre réglage de désinscription. true le réactive.

Appareils de test

Avec debug: kDebugMode, les builds de debug sont des appareils de test. Leurs données sont réelles mais masquées tant que vous n’activez pas Inclure les appareils de test dans Entonnoir et Parcours. Plus d’informations dans Tests.

Confidentialité

  • Pas d’IDFA, pas de Google Advertising ID, pas de demande App Tracking Transparency, pas de fingerprinting.
  • Un identifiant d’installation aléatoire, la version de l’app, la version de l’OS, la version du SDK, téléphone ou tablette, la langue. Le pays vient de la périphérie du réseau. Les adresses IP ne sont jamais stockées.
  • Sur iOS, le manifeste de confidentialité du SDK natif est fourni avec le package : analyse, non liées à l’identité.
  • Ne mettez jamais de noms, d’e-mails ou d’autres données personnelles dans les propriétés des événements.

Dépannage

  • MissingPluginException ? Arrêtez l’app et relancez-la. Le hot reload et le hot restart ne chargent pas le nouveau code natif.
  • Rien dans le tableau de bord ? Activez Inclure les appareils de test : les builds kDebugMode sont masqués par défaut.
  • Toujours rien ? Configurez avec logLevel: UnolinkLogLevel.debug et cherchez Unolink dans la console Xcode ou Logcat. Une clé erronée ou révoquée est consignée comme erreur.

Plus d’informations dans Dépannage.