[Flutter] 1. Integración del SDK de ConsentManager

En este documento encontrarás información general sobre cómo integrar nuestro SDK en tu proyecto. Para obtener más detalles, consulta nuestra documentación de referencia de la API

1. Instalación

consentmanager SDK es una solución integral para gestionar el consentimiento de los usuarios en aplicaciones móviles. Diseñado para gestionar el cumplimiento del RGPD, las preferencias de privacidad de los usuarios y la transparencia en el seguimiento publicitario, este SDK ofrece una integración perfecta para las plataformas iOS y Android. Además, ofrece plugins/puentes de envoltura para React Native, Flutter y Unity, lo que lo hace versátil en diversos entornos de desarrollo.

Pasos: descripción general

  1. Integración y configuración:

    • Integra el SDK en tu aplicación.
    • Configura los ajustes del SDK según tus necesidades.
  2. Creación de una instancia y visualización de la capa de consentimiento:

    • Al iniciar la aplicación, crea una instancia de la CMPManager clase. Esta instancia se encargará del proceso de consentimiento.
    • El SDK mostrará automáticamente la pantalla de consentimiento si es necesario.
  3. Tratamiento de los datos de consentimiento de los usuarios:

    • Una vez recopilados los consentimientos, la información se almacena y está disponible para su consulta a través de diferentes propiedades y métodos expuestos por nuestro SDK. Dispondrás de información sobre los consentimientos rechazados o aceptados, los proveedores y los fines.

1.1 Integración y configuración

La biblioteca wrapper para Flutter está disponible en pub.dev. En la línea de comandos o en la ventana de terminal, ejecuta:

flutter pub add cm_cmp_sdk_v3

Esto añadirá una línea como esta al archivo pubspec.yaml de tu paquete (y ejecutará un flutter pub get):

dependencies:  
	cm_cmp_sdk_v3: ^3.8.0

Como alternativa, es posible que tu editor admita flutter pub get. Consulta la documentación de tu editor para obtener más información.

Además, asegúrate de que el archivo `build.gradle` dentro de la carpeta `android/app` de tu proyecto tiene declarada la dependencia correcta. Se trata de un puente nativo de Flutter/Dart, por lo que todas las dependencias deben estar sincronizadas. Lo mismo se aplica a iOS: asegúrate de que tu archivo `podspec` refleja la dependencia correcta.

Android

dependencies {
    implementation "net.consentmanager.sdkv3:cmsdkv3:3.8.0" // Make sure this line is inserted
}

iOS

  s.dependency "cm-sdk-ios-v3", "3.8.0"
Importar

Ahora, en tu código Dart, puedes usar:

import 'package:cm_cmp_sdk_v3/cm_cmp_sdk_v3.dart';

1.2 Creación de una instancia y visualización de la capa de consentimiento

Dentro de tu código, debes crear una instancia de la clase CMPManager. Tendrás que configurar dos objetos que se pasarán al método getInstance: UrlConfig, que gestiona tu configuración de CMP, como el Code-ID y el idioma predeterminado, y ConsentLayerUIConfig. que configurará el aspecto de la WebView que mostrará la capa de consentimiento. Después de eso, ya estás listo para usar el método checkWithServerAndOpenIfNecessary() para obtener automáticamente los datos necesarios de nuestro servidor y determinar si es necesario mostrar la pantalla de consentimiento o no. Si es así, el SDK mostrará automáticamente la pantalla de consentimiento en este punto, a través de un WebView creada por nuestro SDK, que mostrará la capa de consentimiento con el texto y los botones según tus configuraciones de CMP (elegidas a través del Code-ID de tu CMP), recopilará los datos y guardará la información de consentimiento en el área NSUserDefaults/UserPreferences del dispositivo, para que la aplicación pueda mostrar los anuncios personalizados en consecuencia. 

Ten en cuenta que las funcionalidades relacionadas con determinar si se necesita el consentimiento o no, así como la visualización de la capa de consentimiento, dependen de una conexión de red fiable. Si no hay conexión disponible o si el mecanismo de reintento no logra conectarse a nuestro servidor, el evento didReceiveError devolverá un error de tiempo de espera, por lo que el SDK será totalmente incapaz de determinar la necesidad de un consentimiento, ya que no podrá mostrar la capa de consentimiento. Asegúrate de que tu lógica tenga esto en cuenta.

Ejemplo:

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'CMP SDK Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue),
        useMaterial3: true,
      ),
      home: const MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final CMPmanager _cmpManager = CMPmanager.instance;
  String _lastAction = '';

  @override
  void initState() {
    super.initState();
    _initializeCMP();
  }

  Future<void> _initializeCMP() async {
    try {
      await _cmpManager.setUrlConfig(
        id: "YOUR-CODE-ID-GOES-HERE",
        domain: "delivery.consentmanager.net", // or any other domain from your CMP dashboard
        appName: "CMDemoAppFlutter", // or any other app name, according to 
        language: "EN",
      );

      _cmpManager.addEventListeners(
        didReceiveConsent: (consent, jsonObject) {
          setState(() => _lastAction = 'Received consent: $consent');
        },
        didShowConsentLayer: () {
          setState(() => _lastAction = 'Consent layer shown');
        },
        didCloseConsentLayer: () {
          setState(() => _lastAction = 'Consent layer closed');
        },
        didReceiveError: (error) {
          setState(() => _lastAction = 'Error: $error');
        },
      );
    } catch (e) {
      setState(() => _lastAction = 'Initialization error: $e');
    }
  }
}

En caso de que decidas utilizar un modelo de vista, este sería el aspecto que tendría:

 class CmpViewModel extends ChangeNotifier {
  static final CmpViewModel _instance = CmpViewModel._internal();
  static CmpViewModel get instance => _instance;

  late CMPmanager _cmpSdkPlugin;
  String _callbackLogs = '';

  CmpViewModel._internal();

  Future<void> initCmp() async {
    try {
      _cmpSdkPlugin = CMPmanager.instance;

      await CMPmanager.instance.setUrlConfig(
        appName: "CMDemoAppFlutter",
        id: "YOUR-CODE-ID-GOES-HERE",
        language: "EN",
        domain: "delivery.consentmanager.net",
      );

      _addEventListeners();
      await _cmpSdkPlugin.checkAndOpen();

    } catch (e) {
      _logCallback('Initialization error: $e');
      rethrow;
    }
  }

  void _addEventListeners() {
    _cmpSdkPlugin.addEventListeners(
      didShowConsentLayer: () => _logCallback('Consent layer opened'),
      didCloseConsentLayer: () => _logCallback('Consent layer closed'),
      didReceiveError: (error) => _logCallback('Error: $error'),
      didReceiveConsent: (consent, jsonObject) =>
          _logCallback('Consent: $consentnData: $jsonObject'),
      didChangeATTStatus: (oldStatus, newStatus, last) =>
          _logCallback('ATT Status changed: $oldStatus -> $newStatus'),
    );
  }

  void _logCallback(String message) {
    _callbackLogs = "$messagen$_callbackLogs";
    notifyListeners();
  }

  Future<void> forceOpen() async {
    try {
      await _cmpSdkPlugin.forceOpen();
      Fluttertoast.showToast(msg: 'Opening consent layer');
    } catch (e) {
      Fluttertoast.showToast(msg: 'Error opening consent layer: $e');
    }
  }

  Future<void> getGoogleConsentStatus() async {
    try {
      final settings = await _cmpSdkPlugin.getGoogleConsentModeStatus();
      final message = settings.entries.map((e) => '${e.key}: ${e.value}').join('n');
      _logCallback('Google Consent Mode Settings:n$message');
      Fluttertoast.showToast(msg: 'Check logs for Google Consent Mode settings');
    } catch (e) {
      Fluttertoast.showToast(msg: 'Error getting Google Consent Mode status: $e');
    }
  }
  // .
  // .
  // .
  // all the other method's implementations. 
}

1.3 Tratamiento de los datos de consentimiento de los usuarios

Comprobación de los consentimientos de los usuarios

Nuestro SDK ofrece diferentes métodos para comprobar y recuperar la información de consentimiento. Los métodos principales se muestran en el ejemplo siguiente:

// On the example below retrieved from our Demo App, we have some examples 
// of how to check consents from the user, either accepted or rejected. 

  Future<void> getUserStatus() async {
    try {
      final status = await _cmpSdkPlugin.getUserStatus();
      final message = '''
User Choice: ${status.hasUserChoice}
TCF: ${status.tcf}
Additional Consent: ${status.addtlConsent}
Regulation: ${status.regulation}

Vendors Status:
${status.vendors.entries.map((e) => '${e.key}: ${e.value}').join('n')}

Purposes Status:
${status.purposes.entries.map((e) => '${e.key}: ${e.value}').join('n')}
''';
      _logCallback(message);
      Fluttertoast.showToast(msg: 'Check logs for User Status details');
    } catch (e) {
      Fluttertoast.showToast(msg: 'Error getting user status: $e');
    }
  }

Para obtener más información sobre los demás métodos, consulta nuestra documentación completa de la API

Reabrir la ventana de consentimiento para comprobar las elecciones de los usuarios

Para que el usuario pueda verificar o cambiar sus opciones, basta con llamar a openConsentLayer()

void openConsentLayer() async {
  await _cmpSdkPlugin.forceOpen();
  notifyListeners();
}

Este método mostrará la capa de consentimiento a través de la misma instancia de WebView creada en los pasos anteriores. 

Importación/exportación de información sobre el consentimiento a otras fuentes

En algunos casos, una aplicación nativa puede contener vistas web para mostrar información, como publicidad o contenido. Para transmitir la información de consentimiento desde el SDK a la vista web, puedes recuperar la cadena de consentimiento utilizando:

_cmpSdkPlugin.exportCMPInfo

Esto exportará la información de consentimiento y todos los datos adicionales que necesita el CMP. A continuación, puedes pasar esta información al CMP que se encuentra en tu vista web añadiéndola a la URL que se llama en la vista web.

Si, por el contrario, necesitas importar la cadena de consentimiento utilizando el SDK, puedes usar el ejemplo siguiente:

await _cmpSdkPlugin.importCMPInfo(
          'Q1FERkg3QVFERkg3QUFmR01CSVRCQkVnQUFBQUFBQUFBQWlnQUFBQUFBQUEjXzUxXzUyXzUzXzU0XzU1XzU2XyNfczI3ODlfczI3OTBfczI3OTFfczI2OTdfczk3MV9VXyMxLS0tIw'
      )

Integración con Apple Tracking Transparency (ATT)

En caso de que utilices herramientas de seguimiento o análisis en tu aplicación, te recomendamos que leas la guía sobre la implementación de ATT aquí.

Creación de un diseño personalizado

Para crear una vista personalizada de WKWebView, como cambiar su posición o fondo, por ejemplo, puedes modificar la configuración pasada al objeto ConsentLayerUIConfig de la siguiente manera:

ConsentLayerUIConfig(
    position: .halfScreenTop,
    backgroundStyle: .dimmed(.grey, 0.75),
    cornerRadius: 20,
    respectsSafeArea: false,
    allowsOrientationChanges: true)

Inicio de sesión

Al utilizar nuestro SDK para iOS, es posible que necesites depurar o analizar la información de los registros con diversos fines. Los registros generados por nuestro SDK están etiquetados como «CMP», lo que te permite filtrar fácilmente y ver solo los registros relevantes. Para obtener más información, consulta esta sección de nuestra documentación.

 

 

We do our best to keep this purely informative documentation up to date. However, if you notice that any of these guides need a little touch-up, let us know!