Info
Content

[Eenheid] 1. consentmanager SDK-integratie

Kenmerken

  • Ondersteunt zowel iOS- als Android-platforms.
  • Biedt een brug tussen Unity en native platformspecifieke CMP-functionaliteiten.
  • Hiermee kunt u de toestemming van gebruikers initialiseren, beheren en privacygerelateerde gegevens verwerken.

Ermee beginnen

  1. Installatie:
    • Download de nieuwste uitgave Van de plugin.
    • Importeer het pakket in uw Unity-project met behulp van Activa > Pakket importeren > Aangepast pakket.

Gebruik:

Volg deze stappen om de plug-in te gebruiken.

initialisatie: Om de CMP-functionaliteit te gebruiken, initialiseert u de CMMPanager-instantie.

CmpManager.Instance.Initialize(domain, codeId, appName, language);
                
CmpManager.Instance.OpenConsentLayer();
                

Controleer toestemming: Controleer of de gebruiker toestemming heeft gegeven:

bool hasConsent = CmpManager.Instance.HasConsent();
                

Terugbelverzoeken: terugbellisteners instellen voor verschillende gebeurtenissen:

CmpManager.Instance.AddEventListeners(OnOpen, OnClose, OnNotOpened, OnCmpButtonClicked, OnError);

Doel en leverancierscontroles: Controleer op toestemming met betrekking tot specifieke doeleinden en leveranciers:

bool hasPurpose = CmpManager.Instance.HasPurpose(id);
bool hasVendor = CmpManager.Instance.HasVendor(id);
                

Exportgegevens: CMP-gegevens exporteren:

string cmpString = CmpManager.Instance.ExportCmpString();

 

De configuratie-JSON

In CmpSdkConfig.json kunt u de native SDK-versie voor iOS en Android instellen die voor het bouwproces zal worden gebruikt: 

Vind de compatibele native SDK-versies hier),

{
  "displayName": "Consentmanager SDK",
  "name": "CmpSdk",
  "androidBasePath": "net.consentmanager.sdk",
  "version": "1.0.0",
  "androidLibraryVersion": "x.xx.x",
  "iosLibraryVersion": "x.xx.x",
  "description": "Unity plugin helps you to use native Consentmanager functionality on Android and iOS."
}

Build-instellingen

Ga naar om de build-instellingen te wijzigen Window -> CmpSdk 

pluginwindow-unity.png

iOS Build-instellingen
  • Schakel iOS-buildscript in: Schakel dit in of uit om het buildscript dat verantwoordelijk is voor de integratie van de iOS SDK in het Unity-project in of uit te schakelen.
  • xcFramework-pad: Geef het pad op naar de xcFramework-map. Dit pad kan direct worden bewerkt of er kan naar worden gebladerd via de bijbehorende knop.
  • Versietag opnemen: Indien ingeschakeld, wordt de iOS SDK-versie toegevoegd aan het xcFramework-pad, waardoor versiespecifieke configuraties mogelijk zijn.
  • Resulterend raamwerkpad: Geeft het volledig opgeloste pad naar het xcFramework weer, inclusief de SDK-versie als de versietag is opgenomen.
  • Transparantie van app-tracking inschakelen: Schakel dit in om de App Tracking Transparency-functie voor iOS in te schakelen, wat nodig is voor toestemming van de gebruiker onder de privacyrichtlijnen van iOS.
  • Toestemmingsbericht voor transparantie van app-tracking: Een tekstveld waarin u het aangepaste bericht kunt invoeren dat aan gebruikers wordt weergegeven wanneer toestemming voor tracking wordt gevraagd. Deze boodschap moet duidelijk en beknopt zijn en uitleggen waarom de toestemming nodig is.
Android Build-instellingen
  • Android-buildscript inschakelen: Schakel tussen het in- of uitschakelen van het buildscript voor het integreren van de Android SDK in het Unity-project. 
  • Integreer aangepaste lay-out: Indien ingeschakeld, is het gebruik van een aangepaste lay-out voor de toestemmingslaag mogelijk. Als u dit uitschakelt, wordt de toestemmingslaag standaard op volledig scherm weergegeven. Als uw project geen aangepaste lay-out gebruikt en u deze optie liever uitschakelt. 

Aangepaste lay-out: 

Unity supports different custom layouts: 

        public enum ScreenConfig
        {
            FullScreen,
            HalfScreenBottom,
            HalfScreenTop,
            CenterScreen,
            SmallCenterScreen,
            LargeTopScreen,
            LargeBottomScreen,
        }

Voorbeeld gebruik: 

            _cmpConfig = new CmpConfig(CodeId, Domain, AppName, Language)
            {
                Debug = true,
                Timeout = 8000
            };

                _cmpConfig.UIConfig.screenConfig = (CmpUIConfig.ScreenConfig) Enum.Parse(typeof(CmpUIConfig.ScreenConfig), s);  
                _cmpManager.SetUIConfig(_cmpConfig.UIConfig); 


reference documentation : Get started with Google Firebase for Unity

integratie : Eenheid instellen

To use the google consent mode the CMP Unity SDK supports an interface to set the google consent status: 

// public class CmpSampleScript : MonoBehaviour, IOnCmpGoogleConsentUpdatedCallback { ... 
// Make sure to implement the Interface IOnCmpGoogleConsentUpdatedCallback
public void OnGoogleConsentUpdated(CmpGoogleConsentModeStatus status)
{
// Convert CmpGoogleConsentModeStatus to Firebase compatible dictionary
var firebaseConsentDict = new Dictionary<ConsentType, ConsentStatus>();

foreach (var consent in status.ConsentDictionary)
{
// Convert GoogleConsentType to Firebase ConsentType
var firebaseConsentType = ConvertToFirebaseConsentType(consent.Key);

// Convert GoogleConsentStatus to Firebase ConsentStatus
var firebaseConsentStatus = ConvertToFirebaseConsentStatus(consent.Value);

firebaseConsentDict[firebaseConsentType] = firebaseConsentStatus;
}

// Apply the consent settings to Firebase Analytics
FirebaseAnalytics.SetConsent(firebaseConsentDict);
AppendLog($"Google Consent Mode: {firebaseConsentDict}");
}

private static ConsentType ConvertToFirebaseConsentType(GoogleConsentType googleConsentType)
{
return googleConsentType switch
{
GoogleConsentType.AnalyticsStorage => ConsentType.AnalyticsStorage,
GoogleConsentType.AdStorage => ConsentType.AdStorage,
GoogleConsentType.AdUserData => ConsentType.AdUserData,
GoogleConsentType.AdPersonalization => ConsentType.AdPersonalization,
_ => throw new InvalidEnumArgumentException($"Unknown GoogleConsentType: {googleConsentType}")
};
}

private static ConsentStatus ConvertToFirebaseConsentStatus(GoogleConsentStatus googleConsentStatus)
{
return googleConsentStatus switch
{
GoogleConsentStatus.Granted => ConsentStatus.Granted,
GoogleConsentStatus.Denied => ConsentStatus.Denied,
_ => throw new InvalidEnumArgumentException($"Unknown GoogleConsentStatus: {googleConsentStatus}")
};
}

in this example the OnGoogleConsentUpdate callback is called when the user gives a consent. 

FirebaseAnalytics.SetConsent(firebaseConsentDict);

In this line the Consent Status is set to Firebase Analytics. The other two functions are mapping the CMP Consent Status to the Google Consent Types and Status.

Routekaart voor toekomstige functies:

  • schakelVendorList uit, schakelVendorList in
  • uitschakelenPurposeList, inschakelenPurposeList
  • Cmp ATT Manager voor iOS

Compatibiliteit

  • Eenheid 20XX.XX of later
  • iOS (via DllImport)
  • Android (via JNI)

Support

Voor bugrapporten, functieverzoeken of algemene vragen kunt u terecht open een probleem op de berging.

Vergunningen

Deze plug-in is gelicentieerd onder de MIT-licentie.

credits

Gemaakt en onderhouden door Skander Ben Abdelmalak.

Voorbeeldscript

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Threading;
using CmpSdk.Callbacks;
#if UNITY_IOS
using CmpSdk.Delegates;
#endif
using CmpSdk.Models;
using Firebase.Analytics;
using Firebase.Extensions;
using UnityEngine;
using FirebaseApp = Firebase.FirebaseApp;

namespace CmpSdk.Samples.Scripts
{
    // V prefix for Vendor
    public static class Vendors
    {
        public const string GoogleAnalytics = "S26";
        public const string AmazonAD = "793";
        public const string Facebook = "S7";
        public const string S1 = "S1";
    }

    // P prefix for Purpose
    public static class Purposes
    {
        public const string P1 = "1";
        public const string Marketing = "C2";
        public const string Technical = "S2";
        public const string Security = "S1";
    }


    public class CmpSampleScript : MonoBehaviour, IOnOpenCallback, IOnCloseCallback, IOnCmpNotOpenedCallback,
        IOnCmpButtonClickedCallback, IOnErrorCallback, IOnCmpGoogleConsentUpdatedCallback
    {
        readonly List<string> _purposeList = new() { Purposes.P1, Purposes.Marketing, Purposes.Technical, Purposes.Security };

        readonly List<string> _vendorList = new() { Vendors.S1, Vendors.GoogleAnalytics, Vendors.AmazonAD, Vendors.Facebook };

        // UI elements
        private string _idPurposeOrVendorInputField;
        private string _importStringInputField;
        [SerializeField] private CmpUIManager uiManager;

        // CmpManager Instance
        private CmpConfig _cmpConfig;
        private CmpManager _cmpManager;
        private Thread _mainThread;

        // Configuration constants
        private const string CodeId = "TOOD Your CMP Code ID";
        private const string Domain = "delivery.consentmanager.net";
        private const string AppName = "UnityExample";
        private const string Language = "DE";
        private FirebaseApp _app; 
        
        private void Awake()
        {
            if (!Application.isPlaying)
            {
                Debug.Log("Application is not playing.");
                return;
            }
            
            FirebaseApp.CheckAndFixDependenciesAsync().ContinueWithOnMainThread(task => {
                var dependencyStatus = task.Result;
                if (dependencyStatus == Firebase.DependencyStatus.Available) {
                    // Create and hold a reference to your FirebaseApp,
                    // where app is a Firebase.FirebaseApp property of your application class.
                    _app = FirebaseApp.DefaultInstance;

                    // Set a flag here to indicate whether Firebase is ready to use by your app.
                } else {
                    Debug.LogError($"Could not resolve all Firebase dependencies: {dependencyStatus}");
                    // Firebase Unity SDK is not safe to use here.
                }
            });
            _cmpManager = CmpManager.Instance;
        }
        
        private void Start()
        {
            _cmpConfig = new CmpConfig(CodeId, Domain, AppName, Language)
            {
                Debug = true,
                Timeout = 8000
            };
#if UNITY_ANDROID
            _cmpConfig.UIConfig.isOutsideTouchable = true;
            _cmpConfig.UIConfig.SetAndroidUiType(AndroidUiType.Dialog);
#endif
            // Initialize Consent Manager
            InitializeCmpManager();
            // Initialize UI buttons
            InitializeUIButtons();

            // Launch Consent Manager
            _cmpManager.Launch();
        }

        private void InitializeUIButtons()
        {
            uiManager.CreateButtons(
                new ButtonData("Open", OnClickOpenConsentLayer),
                new ButtonData("Check", OnClickOpenConsentLayerOnCheck),
                new ButtonData("Check?", OnclickCheckConsentRequired),
                new ButtonData("ATT?", OnClickRequestATTrackingStatus),
                new ButtonData("Get Status", OnClickDebugConsentStatus),
                new ButtonData("Initialize", OnClickInitialize),
                new ButtonData("Accept All", OnClickAcceptAll),
                new ButtonData("Reject All", OnClickRejectAll),
                new ButtonData("Reset", OnClickResetConsentData),
                new ButtonData("Import", OnClickImportCmpString),
                new ButtonData("Export", OnClickExportCmpString)
            );
            uiManager.CreateDropdown("Screen Config", GetScreenConfigOptions(), s =>
            {
                AppendLog($"Set Screen ${s}");
                _cmpConfig.UIConfig.screenConfig = (CmpUIConfig.ScreenConfig) Enum.Parse(typeof(CmpUIConfig.ScreenConfig), s);  
                _cmpManager.SetUIConfig(_cmpConfig.UIConfig); 
            });
            uiManager.CreateDropdown("Purposes", _purposeList, s =>
            {
                _idPurposeOrVendorInputField = s;
                CheckHasPurpose(s);
            });
            uiManager.CreateDropdown("Vendors", _vendorList, s =>
            {
                _idPurposeOrVendorInputField = s; 
                CheckHasVendor(s);
            }); 
        }

        private void InitializeCmpManager()
        {
            _mainThread = Thread.CurrentThread;
            AppendLog("Consentmanager SampleScene started");

#if (UNITY_ANDROID || UNITY_IOS) && !UNITY_EDITOR
        _cmpManager.Initialize(_cmpConfig);
        _cmpManager.AddGoogleConsentModeListener(OnGoogleConsentUpdated);
        _cmpManager.AddEventListeners(OnOpen, OnClose, OnNotOpened, OnCmpButtonClicked, OnError);
#endif

#if UNITY_IOS
        CmpATTrackingManager.EnableAutomaticATTracking();
        CmpATTrackingManager.Instance.RegisterOnATTrackingStatusChangedListener(OnCmpATTrackingStatusChanged);
#endif
        }
        
        #region Button Events

        private void OnClickInitialize()
        {
            AppendLog("Initialize");
            _cmpManager.Launch();
        }

        private async void OnClickRejectAll()
        {
            AppendLog("Calling Reject All"); 
            await _cmpManager.RejectAll();
            AppendLog("Rejected All");
        }

        private async void OnClickAcceptAll()
        {
            AppendLog("Calling Accept All");
            await _cmpManager.AcceptAll();
            AppendLog("Accepted All");
        }

        private void OnClickRequestATTrackingStatus()
        {
            AppendLog("Request AT Tracking Status");
            _ = _cmpManager.RequestATTrackingPermission();
        }

        private async void OnclickCheckConsentRequired()
        {
            AppendLog("Calling Check Consent Required");
            var isRequired = await _cmpManager.CheckConsentIsRequired();
            AppendLog($"Is consent required: {isRequired}");
        }

        private void OnClickOpenConsentLayer()
        {
            AppendLog("Open Consent Layer");
            _cmpManager.OpenConsentLayer();
        }

        private void OnClickOpenConsentLayerOnCheck()
        {
            AppendLog("Open Consent Layer on Check");
            _cmpManager.OpenConsentLayerOnCheck();
        }

        private void OnClickImportCmpString()
        {
            AppendLog("Click Import");
            ImportCmpString();
        }

        private void OnClickResetConsentData()
        {
            _cmpManager.Reset();
            AppendLog("Reset");
        }

        private void OnClickDebugConsentStatus()
        {
            DebugConsentStatus();
        }

        private void OnClickExportCmpString()
        {
            var cmpString = _cmpManager.ExportCmpString();
            AppendLog($"Exported CMP String: {cmpString}");
        }

        private void CheckHasPurpose(string purposeId)
        {
            var hasPurpose = _cmpManager.HasPurpose(purposeId);
            AppendLog($"Has Purpose ({purposeId}): {hasPurpose}");
        }

        private void CheckHasVendor(string vendorId)
        {
            var hasVendor = _cmpManager.HasVendor(vendorId);
            AppendLog($"Has Vendor ({vendorId}): {hasVendor}");
        }

        private async void ImportCmpString()
        {
            var cmpString = _importStringInputField;
            CmpImportResult result;

            if (!string.IsNullOrEmpty(cmpString))
            {
                AppendLog($"Importing CMP String from input field: {cmpString}");
                result = await _cmpManager.ImportCmpString(cmpString);
            }
            else
            {
                AppendLog($"Importing CMP String from sample string: {cmpString}");
                result = await _cmpManager.ImportCmpString(cmpString);
            }

            AppendLog($"Unity import result: {result.IsSuccess} with message: {result.Message}");
        }

        #endregion

        #region Callbacks

        public void OnGoogleConsentUpdated(CmpGoogleConsentModeStatus status)
        {
            // Convert CmpGoogleConsentModeStatus to Firebase compatible dictionary
            var firebaseConsentDict = new Dictionary<ConsentType, ConsentStatus>();

            foreach (var consent in status.ConsentDictionary)
            {
                // Convert GoogleConsentType to Firebase ConsentType
                var firebaseConsentType = ConvertToFirebaseConsentType(consent.Key);

                // Convert GoogleConsentStatus to Firebase ConsentStatus
                var firebaseConsentStatus = ConvertToFirebaseConsentStatus(consent.Value);

                firebaseConsentDict[firebaseConsentType] = firebaseConsentStatus;
            }
            
            // Apply the consent settings to Firebase Analytics
            FirebaseAnalytics.SetConsent(firebaseConsentDict);
            AppendLog($"Google Consent Mode: {firebaseConsentDict}");
        }

        private static ConsentType ConvertToFirebaseConsentType(GoogleConsentType googleConsentType)
        {
            return googleConsentType switch
            {
                GoogleConsentType.AnalyticsStorage => ConsentType.AnalyticsStorage,
                GoogleConsentType.AdStorage => ConsentType.AdStorage,
                GoogleConsentType.AdUserData => ConsentType.AdUserData,
                GoogleConsentType.AdPersonalization => ConsentType.AdPersonalization,
                _ => throw new InvalidEnumArgumentException($"Unknown GoogleConsentType: {googleConsentType}")
            };
        }

        private static ConsentStatus ConvertToFirebaseConsentStatus(GoogleConsentStatus googleConsentStatus)
        {
            return googleConsentStatus switch
            {
                GoogleConsentStatus.Granted => ConsentStatus.Granted,
                GoogleConsentStatus.Denied => ConsentStatus.Denied,
                _ => throw new InvalidEnumArgumentException($"Unknown GoogleConsentStatus: {googleConsentStatus}")
            };
        }

        public void OnClose()
        {
            LogThreadContext("OnClose");
            AppendLog("CMPConsentTool closed");
        }

        public void OnCmpButtonClicked(CmpButtonEvent buttonEvent)
        {
            LogThreadContext("OnCmpButtonClicked");
            AppendLog($"CMPButton clicked. Event: {buttonEvent}");
        }

        public void OnNotOpened()
        {
            LogThreadContext("OnNotOpened");
            AppendLog("CMPConsentTool not opened");
        }

        public void OnError(CmpErrorType errorType, string message)
        {
            LogThreadContext("OnError");
            AppendLog($"Error: {errorType}, {message}");
        }

        public void OnOpen()
        {
            LogThreadContext("OnOpen");
            AppendLog("CMPConsentTool opened");
        }
#if UNITY_IOS 
        private void OnCmpATTrackingStatusChanged(ATTrackingManagerAuthorizationStatus oldStatus,
            ATTrackingManagerAuthorizationStatus newStatus, double lastUpdated)
        {
            var unixTime = lastUpdated;
            var dtDateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
            dtDateTime = dtDateTime.AddSeconds(unixTime).ToLocalTime();
            AppendLog("OnCmpATTrackingStatusChanged: " + newStatus + " lastUpdated: " + dtDateTime);
        }
#endif
        
        #endregion

        private void DebugConsentStatus()
        {
            var hasConsent = _cmpManager.HasConsent();
            var allPurposes = _cmpManager.GetAllPurposes();
            var disabledPurposes = _cmpManager.GetAllPurposes();
            var enabledPurposes = _cmpManager.GetEnabledPurposes();
            var allVendors = _cmpManager.GetAllVendors();
            var disabledVendors = _cmpManager.GetDisabledVendors();
            var enabledVendors = _cmpManager.GetEnabledVendors();
            var exportCmp = _cmpManager.ExportCmpString();
            
            AppendLog("-----------------");
            AppendLog($"Unity All Purposes: {string.Join(", ", allPurposes)}");
            AppendLog($"Unity Disabled Purposes: {string.Join(", ", disabledPurposes)}");
            AppendLog($"Unity Enabled Purposes: {string.Join(", ", enabledPurposes)}");
            AppendLog($"Unity All Vendors: {string.Join(", ", allVendors)}");
            AppendLog($"Unity Disabled Vendors: {string.Join(", ", disabledVendors)}");
            AppendLog($"Unity Enabled Vendors: {string.Join(", ", enabledVendors)}");
            AppendLog($"Unity Exported CMP String: {exportCmp}");
            AppendLog($"Unity Has Consent: {hasConsent}");
            AppendLog($"Unity US Privacy String: {_cmpManager.GetUsPrivacyString()}");
            AppendLog($"Unity Google Ac String: {_cmpManager.GetGoogleAcString()}");
            AppendLog($"Unity Has Purpose C1: {_cmpManager.HasPurpose("c1")}");
            AppendLog($"Unity Has Vendor 10: {_cmpManager.HasVendor("628")}");
            AppendLog($"Unity Google Consent Mode Status: {_cmpManager.GetGoogleConsentModeStatus()}");
            AppendLog("-----------------");
        }

        #region Helper

        private void LogThreadContext(string callbackName)
        {
            var onMainThread = IsMainThread();
            var threadId = Thread.CurrentThread.ManagedThreadId;
            AppendLog($"{callbackName} called. Is main thread: {onMainThread} ID: {threadId}");
        }

        private bool IsMainThread()
        {
            return _mainThread.Equals(Thread.CurrentThread);
        }

        private void AppendLog(string message)
        {
            Debug.Log(message); 

            if (uiManager != null)
            {
                uiManager.AddLogText(message);
            }
        }
                
        private List<string> GetScreenConfigOptions()
        {
            var options = new List<string>();
            foreach (var config in Enum.GetValues(typeof(CmpUIConfig.ScreenConfig)))
            {
                options.Add(config.ToString());
            }

            return options;
        }

        #endregion
    }
}
Terug naar boven