Compliant with GDPR, CCPA, COPPA, LGPD, PECR, PDPA, PIPEDA, and more.
UniConsent CMP est un package pour la gestion du consentement RGPD IAB TCF 2.4 dans les applications Flutter. Vous pouvez trouver une application de démonstration intégrée avec UniConsent CMP dans le répertoire "uniconsent_demo".
Pour inclure le package UniConsent dans votre projet Flutter, ajoutez-le en tant que dépendance dans votre fichier pubspec.yaml :
dependencies:
uniconsent:
path: ../uniconsent
Ensuite, synchronisez la dépendance en exécutant la commande suivante :
flutter pub get
Avant d'intégrer le SDK, personnalisez l'apparence de la bannière de consentement dans le tableau de bord UniConsent pour correspondre à votre marque et optimiser les taux de consentement.
Accédez à Projects → Sélectionnez votre projet → Settings → Step 5: UI & Style Settings pour configurer :
Pour un contrôle plus précis, ajoutez du CSS personnalisé dans le champ CSS Content sous l'étape 5. Cela est recommandé pour donner à la bannière un aspect natif dans votre application et obtenir le meilleur taux de consentement :
/* Example: Style the accept button to match your brand */
.unic-btn-accept {
background-color: #4CAF50;
border-radius: 8px;
font-weight: 600;
}
/* Example: Adjust banner font */
.unic-banner {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}
/* Example: Make the reject button less prominent */
.unic-btn-reject {
background-color: transparent;
border: 1px solid #ccc;
color: #666;
}
Conseil : Une interface de consentement bien adaptée à votre marque et à l'aspect natif de votre application obtient généralement des taux de consentement plus élevés. Les utilisateurs sont plus enclins à réagir positivement à une bannière qui correspond à l'apparence et au ressenti qu'ils attendent.
Pour utiliser la CMP UniConsent dans votre application, suivez ces étapes :
Initialisez la CMP avec un App ID fourni par votre gestionnaire de compte :
// Init CMP with appId
UniConsent.instance.setAppId("YOUR_APP_ID_CHANGE_THIS");
// Set language (Optional)
UniConsent.instance.setLanguage("EN");
Affichez l'interface de la CMP :
// Display CMP as full-screen page (default)
UniConsent.instance.launchCMP(context);
// Display CMP as a modal bottom sheet
UniConsent.instance.launchCMP(context, displayMode: CMPDisplayMode.modalSheet);
// Display CMP as a modal bottom sheet at 70% of the available height
UniConsent.instance.launchCMP(
context,
displayMode: CMPDisplayMode.modalSheet,
heightRatio: 0.7,
);
// Display CMP as a center dialog
UniConsent.instance.launchCMP(context, displayMode: CMPDisplayMode.dialog);
// Display CMP as a center dialog at 85% width and 70% height
UniConsent.instance.launchCMP(
context,
displayMode: CMPDisplayMode.dialog,
widthRatio: 0.85,
heightRatio: 0.7,
);
Disponible à partir de la version 26.8.0 du SDK.
Les deux ratios sont optionnels — chaque mode d'affichage fonctionne sans eux. Ne passez un ratio (une fraction de l'espace disponible, supérieure à 0 et au plus égale à 1) que pour remplacer la taille par défaut ; les valeurs invalides lèvent une ArgumentError :
| Paramètre | S'applique à | Valeur par défaut si omis |
|---|---|---|
heightRatio | modalSheet, dialog | Panneau : 90 % de la hauteur. Dialogue : 70 % |
widthRatio | dialog uniquement | 90 % de la largeur, jusqu'à 500 pixels logiques |
Les ratios qui ne s'appliquent pas au mode d'affichage choisi sont ignorés (page ignore les deux).
Écoutez les événements du cycle de vie du SDK avec subscribe(). C'est la méthode recommandée pour savoir quand l'interface est affichée et quand elle est fermée.
Événements disponibles (CMPEventType) :
CMPEventType.uiDisplay — L'interface de consentement est affichéeCMPEventType.uiClose — L'interface de consentement est ferméeUniConsent.instance.subscribe((event) {
switch (event.type) {
case CMPEventType.uiDisplay:
print('CMP UI displayed');
break;
case CMPEventType.uiClose:
print('CMP UI closed');
break;
default:
break;
}
});
Écoutez les changements de consentement avec un callback optionnel :
// Display CMP UI with consent change callback
UniConsent.instance.launchCMP(context, onConsentChanged: (info) {
// Called when the user saves consent choices
print('Consent updated: ${info?.tcString}');
});
Pour un contrôle total, utilisez buildCMPWidget() pour intégrer la CMP dans votre propre mise en page :
// Embed in your own widget tree
UniConsent.instance.buildCMPWidget(
onConsentChanged: (info) { /* ... */ },
onClose: () { /* dismiss your custom UI */ },
);
Vérifier automatiquement si le consentement est nécessaire au lancement de l'application :
// Check if consent should be requested (e.g. first visit, or vendor list updated)
final shouldRequest = await UniConsent.instance.shouldRequestConsent();
if (shouldRequest) {
UniConsent.instance.launchCMP(context);
}
Obtenir le tcString si nécessaire :
// Get tcString
final info = await UniConsent.instance.getConsentInfo();
print(info?.tcString);
Lire le statut du consentement :
// Read consent status
final info = await UniConsent.instance.getConsentInfo();
if (info is ConsentInfo &&
info.purposeConsents.contains(DataUsagePurpose.useLimitedDataToSelectAds)) {
// do something
}
Réinitialiser le statut du consentement si nécessaire :
// Clear all consent data
await UniConsent.instance.clearAll();
Disponible à partir de la version 26.7.0 du SDK. Si vous créez votre propre interface de consentement de premier niveau au lieu d'afficher la webview du CMP, vous pouvez enregistrer le consentement directement :
// Grant consent for all purposes, special features and vendors
final saved = await UniConsent.instance.agreeAll();
// Reject all purposes, special features and vendors
final saved = await UniConsent.instance.rejectAll();
Ces deux API enregistrent les mêmes valeurs de consentement que le flux de l'interface CMP (clés IAB TCF, consentement additionnel et signaux de consent mode) et déclenchent le même événement de fermeture pour les abonnés.
Pour les utilisateurs des États-Unis et du Canada, les deux API enregistrent aussi le choix CCPA, US State Privacy et IAB TCF Canada qui les concerne, selon les mêmes règles que l'interface de la CMP, et écrivent les clés IAB GPP et US Privacy. Activez les modes API-Only dans les paramètres du projet du tableau de bord UniConsent pour que la bannière de la CMP ne s'affiche pas dans ces régions.
Elles enregistrent aussi le choix des catégories de cookies là où une bannière de catégories de cookies s'applique (toutes les catégories, ou seulement Strictement nécessaires), ainsi que les finalités et fournisseurs personnalisés du projet.
Pour savoir quel premier niveau afficher, appelez getPolicy() (à partir de la version 26.10.0 du SDK). Elle renvoie la politique qui s'applique à l'utilisateur, selon les mêmes règles que la CMP : gdpr (IAB TCF), tcfca (IAB TCF Canada), uss (US State Privacy), ccpa, categories (voir Catégories de cookies ci-dessous) ou none.
final cmp = UniConsent.instance;
if (await cmp.shouldRequestConsent()) {
// l'utilisateur doit faire un choix : affichez votre premier niveau pour cette politique
final policy = await cmp.getPolicy(); // gdpr, tcfca ou categories
}
Remarque : Ces API récupèrent la liste des fournisseurs et la configuration du projet via le réseau et renvoient
falsesi le consentement n'a pas pu être enregistré (par exemple hors ligne).Important : Votre premier niveau personnalisé doit toujours respecter les exigences de l'IAB TCF (divulguer les finalités et les fournisseurs, et proposer l'acceptation et le refus avec la même visibilité). Les utilisateurs doivent toujours pouvoir ouvrir l'interface CMP complète (
launchCMP()) pour effectuer des choix granulaires.
Si votre application ouvre une WebView qui charge une page web avec le tag CMP UniConsent, vous pouvez transmettre le statut de consentement natif afin que le tag CMP reconnaisse le consentement existant et n'affiche pas à nouveau la bannière.
import 'package:webview_flutter/webview_flutter.dart';
import 'package:uniconsent/uniconsent.dart';
final controller = WebViewController();
controller
..setJavaScriptMode(JavaScriptMode.unrestricted)
..setNavigationDelegate(NavigationDelegate(
onPageStarted: (url) async {
// Inject consent at page start, before CMP tag runs
await UniConsent.instance.syncConsent(controller);
},
))
..loadRequest(Uri.parse('https://example.com'));
Les types suivants sont disponibles lors de l'import de package:uniconsent/uniconsent.dart :
UniConsent — singleton principal du SDKUniConsentInfo — données de consentement de base (sdkId, tcString, gdprApplies, vendorListVersion, etc.)ConsentInfo — étend UniConsentInfo avec les listes de consentement par finalitéDataUsagePurpose — enum des identifiants de finalité IAB TCF 2.4KVDBKeys — constantes de clés de stockage IAB TCF (par ex. KVDBKeys.tcString, KVDBKeys.purposeConsents)CMPDisplayMode — enum pour le style d'affichage (page, modalSheet, dialog)CMPEventType — enum pour les événements du cycle de vie (le SDK émet uiDisplay et uiClose)CMPEvent — objet événement avec une propriété typeCMPEventCallback — typedef pour le callback de subscribe()LogLevel — debug / prodConsentCallback — typedef pour le callback onConsentChangedUniConsentCMPContent — le widget CMP principal pour les mises en page personnaliséesOuvrez la CMP sur un écran précis, par exemple depuis un lien « Paramètres de confidentialité » de votre app. L'écran demandé s'ouvre toujours. Pour les utilisateurs aux États-Unis, les écrans de paramètres ouvrent les paramètres CCPA ou US State Privacy qui s'appliquent à eux. Les utilisateurs au Canada voient la version IAB TCF Canada des écrans IAB TCF.
| Écran | Affiche |
|---|---|
CMPStage.gdprFirstScreen | Premier niveau (bannière) |
CMPStage.gdprSecondScreen | Paramètres (finalités) |
CMPStage.gdprVendorsScreen | Fournisseurs |
CMPStage.ccpaFirstScreen | Premier niveau CCPA |
CMPStage.ccpaSecondScreen | Paramètres CCPA |
CMPStage.usStateFirstScreen | Premier niveau US State Privacy |
CMPStage.usStateSecondScreen | Paramètres US State Privacy |
CMPStage.categoriesFirstScreen | Premier niveau des catégories de cookies (bannière) |
CMPStage.categoriesSecondScreen | Paramètres des catégories de cookies |
final cmp = UniConsent.instance;
// ouvrir l'écran des paramètres
cmp.launchCMP(context, stage: CMPStage.gdprSecondScreen);
// ouvrir la CMP seulement si un consentement est nécessaire (UE et IAB TCF Canada) ; indique si elle s'est ouverte
final opened = await cmp.launchCMPIfNeeded(context);
// journaux de débogage ; utilisez LogLevel.prod dans les builds de production
cmp.setLogLevel(LogLevel.debug);
// pour les tests uniquement : afficher la CMP comme pour un utilisateur d'une autre région, "EU", "CA" (Canada), "CAQC" (Québec), "US" suivi d'un code d'État comme "USCA" ou "USTX", "BR", "CN", "ZA", "VN" ou tout autre code pays, ou "N" (hors de ces régions). S'applique aussi à getPolicy() et à shouldRequestConsent() ; à retirer des builds de production
cmp.setTestRegion("CA");
// code pays de l'utilisateur ("AA" si inconnu) et, pour les États-Unis et le Canada, le code de l'État ou de la province
final geo = await cmp.getGEO();
final state = await cmp.getGEOState();
La CMP enregistre les clés IAB GPP et la clé US Privacy dans le stockage natif de l'app (SharedPreferences sous Android, UserDefaults sous iOS), telles que les définissent les spécifications de l'IAB. Les SDK publicitaires de votre app les lisent à cet endroit ; aucune modification de code n'est nécessaire. Les clés GPP sont écrites lorsque GPP, US State Privacy ou IAB TCF Canada est activé dans les paramètres du projet du tableau de bord UniConsent. La clé US Privacy est écrite dès que le CCPA est activé.
| Clé | Valeur |
|---|---|
IABGPP_HDR_Version | Version GPP (1) |
IABGPP_HDR_Sections | ID des sections présentes dans la chaîne GPP, séparés par _ |
IABGPP_HDR_GppString | La chaîne GPP complète |
IABGPP_GppSID | ID des sections qui s'appliquent à l'utilisateur, séparés par _, ou -1 si aucune ne s'applique |
IABGPP_2_String | Chaîne IAB TCF EU, lorsque le RGPD s'applique |
IABGPP_5_String | Chaîne IAB TCF Canada, lorsque le TCF Canada s'applique |
IABGPP_6_String | Chaîne US Privacy, lorsque le CCPA s'applique |
IABGPP_7_String | Chaîne US National (usnat), lorsque US State Privacy ou le CCPA s'applique |
IABGPP_8_String à IABGPP_27_String | La section de l'État de l'utilisateur (8 Californie à 27 Rhode Island), lorsque US State Privacy s'applique, ou la Californie avec le CCPA, selon le paramètre GPP Sections |
IABUSPrivacy_String | Chaîne US Privacy dès que le CCPA est activé : le choix de l'utilisateur dans la région CCPA, sinon 1--- |
Les clés sont mises à jour à chaque chargement de la CMP et après chaque choix de consentement. Lorsque GPP est désactivé, les clés IABGPP_ sont supprimées.
Les apps prennent en charge les mêmes options pour les États-Unis et le Canada que les sites web : CCPA, US State Privacy (avec la liste des États et les paramètres GPP Sections et MSPA) et IAB TCF Canada. shouldRequestConsent() renvoie true pour les utilisateurs du Canada concernés par l'IAB TCF Canada tant qu'ils n'ont pas fait de choix. La confidentialité aux États-Unis fonctionne par opposition (opt-out) : les utilisateurs américains ne sont pas sollicités d'eux-mêmes, ils voient la bannière ou les paramètres américains lorsque votre app ouvre la CMP, par exemple depuis un lien vers les paramètres de confidentialité. D'ici là, lorsque le CCPA ou US State Privacy est activé, le SDK écrit les clés US Privacy et GPP par défaut pour les utilisateurs américains sans rien afficher : sans opposition, ou avec opposition lorsque le suivi publicitaire est désactivé sur l'appareil. US State Privacy est désactivé au départ pour les nouveaux projets Mobile App ; activez-le dans le tableau de bord.
Lorsque l'utilisateur a désactivé le suivi publicitaire sur l'appareil, la CMP le traite comme un refus américain de la vente, du partage et de la publicité ciblée, comme le fait Global Privacy Control sur les sites web. Sous iOS, il s'agit du suivi non autorisé dans App Tracking Transparency ; sous Android, d'un identifiant publicitaire supprimé ou de la limitation du suivi publicitaire, lus via les services Google Play lorsque votre app les inclut. Un choix que l'utilisateur enregistre ensuite dans la bannière est prioritaire.
Le SDK renvoie aussi les chaînes enregistrées :
final gppString = await UniConsent.instance.getGPPString();
final gppSid = await UniConsent.instance.getGPPSID();
final usPrivacy = await UniConsent.instance.getUSPrivacyString();
Disponible à partir de la version 26.10.0 du SDK. Lorsqu'une région utilise des catégories de cookies au lieu de l'IAB TCF ou des politiques américaines, la CMP affiche une bannière avec quatre catégories : Strictement nécessaires, Performance, Fonctionnalité, et Ciblage ou publicité. Cela s'applique à :
Les catégories en opt-in démarrent avec seulement Strictement nécessaires activée, et shouldRequestConsent() renvoie true tant que l'utilisateur n'a pas fait de choix, puis à nouveau après un changement de version de configuration. Les catégories en opt-out démarrent avec toutes les catégories activées (Ciblage désactivé lorsque le suivi publicitaire est désactivé sur l'appareil aux États-Unis), et l'app ne sollicite pas l'utilisateur d'elle-même : il les modifie depuis votre lien vers les paramètres de confidentialité. L'opt-out s'applique à une règle opt-out pour les autres pays et, dans les apps, à un projet Consent Categories aux États-Unis.
Ouvrez les écrans des catégories avec CMPStage.categoriesFirstScreen (bannière) et CMPStage.categoriesSecondScreen (paramètres). setTestRegion() accepte aussi BR, CN, ZA, VN et d'autres codes pays, pour tester ces régions.
Disponible à partir de la version 26.10.0 du SDK. Les finalités personnalisées et les fournisseurs personnalisés que vous ajoutez dans les paramètres du projet du tableau de bord UniConsent s'affichent dans les écrans de la CMP : les finalités personnalisées dans le premier niveau et les paramètres IAB TCF et dans les paramètres des catégories de cookies, les fournisseurs personnalisés dans la liste des fournisseurs IAB TCF. Dans les paramètres CCPA et US State Privacy, seules les finalités personnalisées sensibles sont listées. Dans les paramètres des catégories de cookies, les fournisseurs personnalisés suivent la catégorie Ciblage ou publicité. Là où l'IAB TCF ne s'applique pas (catégories de cookies et États-Unis), les fournisseurs personnalisés sont listés en lecture seule dans la liste des fournisseurs du menu, et dans les paramètres des catégories de cookies sous Ciblage ou publicité.
Pour démarrer ou arrêter vos propres SDK selon eux, demandez au SDK si l'app peut utiliser maintenant une finalité personnalisée ou un fournisseur personnalisé. La réponse suit la politique de l'utilisateur, selon les mêmes règles que la CMP utilise pour les balises :
final cmp = UniConsent.instance;
if (await cmp.isCustomPurposeConsented(1)) {
// démarrez le SDK couvert par votre finalité personnalisée 1
}
final vendorAllowed = await cmp.isCustomVendorConsented(2);
final all = await cmp.getCustomConsents(); // {'purposes': {'1': true}, 'vendors': {'2': false}}
Appelez-les de nouveau après la fermeture de la CMP ou un changement du consentement. Les identifiants que le projet n'a pas, et tous les identifiants avant que le SDK soit prêt, renvoient false.
La CMP peut lister les SDK tiers de votre app (régies publicitaires, analytique, attribution et autres) avec leur société, leur utilisation et leur politique de confidentialité. Les utilisateurs les voient dans la liste des fournisseurs, en lecture seule dans toutes les régions : il n'y a pas d'interrupteurs, et votre app continue d'activer ou de désactiver chaque SDK selon les choix de l'utilisateur pour les finalités ou les catégories de cookies.
Pour définir la liste, activez Enable Third-party SDKs dans Step 4: Advanced Features de votre projet d'app, choisissez vos SDK dans l'onglet Third-party SDKs ou ajoutez les vôtres, puis enregistrez et publiez. Aucun code n'est nécessaire dans votre app.
getGPPString(), getGPPSID() et getUSPrivacyString()launchCMP(context, stage:) ; ajout de launchCMPIfNeeded(), getGEO() et getGEOState()CMPStage.ccpaFirstScreen et CMPStage.usStateFirstScreen ; ajout de setTestRegion() pour tester la CMP comme un utilisateur d'une autre région, par exemple le CanadaCMPStage.categoriesFirstScreen et CMPStage.categoriesSecondScreengetPolicy() ; agreeAll() et rejectAll() enregistrent aussi les catégories de cookies, les finalités personnalisées et les fournisseurs personnaliséssetTestRegion() accepte aussi BR, CN, ZA, VN et d'autres codes pays, et s'applique à getPolicy() et à shouldRequestConsent()isCustomPurposeConsented(), isCustomVendorConsented() et getCustomConsents() : les finalités et fournisseurs personnalisés que l'app peut utiliser maintenant selon la politique de l'utilisateur