SDK de Flutter - Compatible con SKAdNetwork

Documento

Apoyo a SKAdNetwork

SKAdNetwork es el marco de atribución centrado en la privacidad de Apple para campañas de instalación de aplicaciones iOS. El SDK de Singular Flutter habilita SKAdNetwork por defecto en modo gestionado, donde Singular actualiza automáticamente los valores de conversión basándose en el modelo de conversión configurado en el panel de control.

No requiere configuración adicional: Si está utilizando la última SDK de Flutter, SKAdNetwork funciona fuera de la caja. No se necesitan cambios de código ni configuraciones adicionales para la funcionalidad básica.

Modos de SKAN

Modo gestionado (por defecto)

En el modo gestionado, Singular gestiona automáticamente las actualizaciones de los valores de conversión basándose en el modelo de conversión configurado en el panel de control. Este es el enfoque recomendado para la mayoría de las aplicaciones, ya que requiere un código mínimo y proporciona un seguimiento óptimo de las conversiones.

  • Actualizaciones automáticas: Singular gestiona todas las actualizaciones de los valores de conversión en función de los eventos del usuario y del modelo configurado.
  • Configuración del cuadro de mando: Diseñe su modelo de conversión en el cuadro de mandos de Singular sin cambios en el código.
  • Optimización: Benefíciese de la experiencia de Singular para maximizar las actualizaciones del valor de conversión dentro de las restricciones de Apple.
  • Gestión de ventanas 24 horas: Singular gestiona la ventana de actualización de 24 horas de SKAdNetwork de forma inteligente para maximizar la recogida de datos.

Modo Manual (Avanzado)

El modo manual le ofrece un control total sobre las actualizaciones de los valores de conversión, permitiéndole implementar una lógica personalizada para determinar cuándo y cómo actualizar los valores de conversión de SKAN. Utilice este modo sólo si tiene requisitos específicos que el Modo Manual no puede cumplir.

Función avanzada: El Modo Manual requiere una cuidadosa implementación y comprensión de las restricciones de SKAdNetwork de Apple, incluyendo las ventanas y limitaciones de actualización de los valores de conversión. La mayoría de las aplicaciones deberían utilizar el Modo Gestionado.

Desactivación del soporte SKAdNetwork

El seguimiento de SKAdNetwork está activado por defecto. Para desactivarlo, establezca la propiedad de configuración skAdNetworkEnabled en false cuando construya su objeto SingularConfig.

Dart
import 'package:singular_flutter_sdk/singular_config.dart';

SingularConfig config = SingularConfig('API_KEY', 'SECRET');
config.skAdNetworkEnabled = false; // Disable SKAdNetwork

Configuración del modo manual

Para implementar una lógica de valores de conversión personalizada, active el modo manual y utilice los métodos del SDK proporcionados para actualizar y supervisar los valores de conversión a lo largo del ciclo de vida de su aplicación.

Activación del modo manual

Establezca la propiedad de configuración manualSkanConversionManagement en true al crear el objeto SingularConfig para tomar el control de las actualizaciones de los valores de conversión.

Dart
import 'package:singular_flutter_sdk/singular_config.dart';

SingularConfig config = SingularConfig('API_KEY', 'SECRET');
config.manualSkanConversionManagement = true; // Enable manual mode

Importante: Los métodos de actualización manual sólo funcionan cuando manualSkanConversionManagement está activado. Si el modo gestionado está activado, se ignorarán las actualizaciones manuales.

Actualizar valor de conversión (SKAN 2.0-3.0)

Utilice el método skanUpdateConversionValue para actualizar manualmente el valor de conversión de SKAdNetwork basándose en su lógica personalizada. El valor de conversión debe ser un número entero comprendido entre 0 y 63.

Firma del método

Dart
static void skanUpdateConversionValue(int conversionValue)

Ejemplo de uso

Dart
import 'package:singular_flutter_sdk/singular.dart';
import 'dart:io';

// User completed signup - update conversion value to 7
void onUserSignUp() {
  if (Platform.isIOS) {
    // Track the sign-up event
    Singular.event('SignUp');

    // Update SKAN conversion value
    Singular.skanUpdateConversionValue(7);
    print('Conversion value updated to 7');
  }
}

// User completed purchase - update based on purchase amount
void onPurchaseComplete(double purchaseAmount) {
  if (Platform.isIOS) {
    // Track revenue event
    Singular.customRevenue('Purchase', 'USD', purchaseAmount);

    // Calculate conversion value based on purchase tier
    int conversionValue = calculateConversionValue(purchaseAmount);
    Singular.skanUpdateConversionValue(conversionValue);
    print('Conversion value updated to $conversionValue');
  }
}

int calculateConversionValue(double amount) {
  // Your custom logic to determine conversion value
  if (amount >= 100) return 63;  // High value
  if (amount >= 50) return 40;   // Medium value
  if (amount >= 10) return 20;   // Low value
  return 10;                      // Minimal value
}

Actualizar valores de conversión (SKAN 4.0)

Para iOS 16.1+, utilice el método skanUpdateConversionValues para actualizar los valores de conversión de SKAdNetwork 4.0 con parámetros de valor fino, valor grueso y bloqueo. Esto proporciona un control más granular sobre las actualizaciones de los valores de conversión.

Firma del método

Dart
static void skanUpdateConversionValues(
  int conversionValue,  // Fine value (0-63)
  int coarse,           // Coarse value (0=low, 1=medium, 2=high)
  bool lock             // Lock status
)

Ejemplo de uso

Dart
import 'package:singular_flutter_sdk/singular.dart';
import 'dart:io';

void updateSKAN4ConversionValue(
  int fineValue, 
  String coarseValue,
  bool shouldLock
) {
  if (Platform.isIOS) {
    // Map coarse value string to number
    Map<String, int> coarseMap = {
      'low': 0, 
      'medium': 1, 
      'high': 2
    };

    // Update SKAdNetwork 4.0 conversion values
    Singular.skanUpdateConversionValues(
      fineValue,
      coarseMap[coarseValue] ?? 0,
      shouldLock
    );

    print('SKAN 4.0 updated: fine=$fineValue, coarse=$coarseValue, lock=$shouldLock');
  }
}

// Example: High-value user completes tutorial
void onTutorialComplete() {
  updateSKAN4ConversionValue(15, 'medium', false);
}

// Example: Premium purchase - lock the value
void onPremiumPurchase() {
  updateSKAN4ConversionValue(63, 'high', true);
}

Obtener valor de conversión actual

Recupera el valor de conversión actual rastreado por Singular SDK. Esto es útil para implementar lógica condicional basada en el estado actual y funciona tanto en modo Gestionado como Manual.

Firma del método

Dart
static Future<int> skanGetConversionValue()

Ejemplo de uso

Dart
import 'package:singular_flutter_sdk/singular.dart';
import 'dart:io';

Future<void> checkAndUpdateConversionValue() async {
  if (Platform.isIOS) {
    int currentValue = await Singular.skanGetConversionValue();
    print('Current conversion value: $currentValue');

    // Only update if current value is below threshold
    if (currentValue < 30) {
      Singular.skanUpdateConversionValue(30);
      print('Updated conversion value to 30');
    }
  }
}

Monitorizar actualizaciones del valor de conversión

Configure un controlador para recibir notificaciones en tiempo real cada vez que cambie el valor de conversión. Esto le permite reaccionar a las actualizaciones del valor de conversión y registrar análisis o activar otros comportamientos de la aplicación.

Configuración

Configure el controlador de actualización del valor de conversión utilizando la propiedad conversionValueUpdatedCallback al inicializar el SDK.

Dart
import 'package:singular_flutter_sdk/singular.dart';
import 'package:singular_flutter_sdk/singular_config.dart';

void initializeSingularSDK() {
  SingularConfig config = SingularConfig('API_KEY', 'SECRET');

  // Set up conversion value update handler
  config.conversionValueUpdatedCallback = (int conversionValue) {
    print('Conversion value updated to: $conversionValue');

    // Log the update to your analytics
    logConversionValueUpdate(conversionValue);

    // Trigger app-specific behavior
    if (conversionValue >= 50) {
      unlockPremiumFeature();
    }
  };

  Singular.start(config);
}

void logConversionValueUpdate(int value) {
  // Your analytics logging logic
  print('Analytics: SKAN CV = $value');
}

void unlockPremiumFeature() {
  // Your custom logic
  print('Premium feature unlocked based on high conversion value');
}

Práctica recomendada: Utilice el controlador de valores de conversión para mantener una vista sincronizada del estado de conversión actual en toda la aplicación. Esto es especialmente útil para depurar y asegurarse de que su lógica personalizada funciona correctamente.


Compatibilidad con App Tracking Transparency (ATT)

App Tracking Transparency (ATT) es el marco de privacidad de Apple que requiere el consentimiento del usuario antes de acceder al IDFA (identificador para anunciantes) del dispositivo y compartir los datos del usuario. Implementar ATT correctamente es fundamental para la atribución de iOS y maximizar la precisión de sus campañas de adquisición de usuarios.

Por qué la ATT es importante para la atribución

A partir de iOS 14.5, las apps deben solicitar permiso al usuario a través del marco ATT antes de acceder al IDFA. Aunque la atribución sigue siendo posible sin el IDFA utilizando métodos de huella digital y probabilísticos, disponer del IDFA mejora significativamente la precisión de la atribución y proporciona una correspondencia determinista.

  • Atribución determinista: El IDFA permite una atribución precisa a nivel de dispositivo que conecta directamente las impresiones publicitarias con las instalaciones.
  • Optimización de la red publicitaria: Las redes publicitarias pueden optimizar mejor las campañas y proporcionar informes más precisos con el acceso al IDFA.
  • Información a nivel de usuario: El acceso al IDFA permite un análisis más granular del comportamiento del usuario y el seguimiento de cohortes.

Recomendación: Singular recomienda encarecidamente implementar el aviso ATT y solicitar el consentimiento del usuario. Explique los beneficios a los usuarios (anuncios personalizados, mejor experiencia de aplicación) para maximizar las tasas de opt-in.

Requisitos de implementación

Para iOS 14.5+ (incluido iOS 18), utilice el framework ATTrackingManager para solicitar el consentimiento del usuario antes de acceder al IDFA para el seguimiento. El SDK de Singular es compatible con ATT, permitiendo la inicialización antes del consentimiento y retrasando los eventos hasta que se concede el consentimiento o se produce un tiempo de espera.

Paso 1: Añadir configuración del marco ATT

Configure su aplicación iOS para que admita el marco ATT actualizando su archivo Info.plist con una descripción de uso orientada al usuario.

  1. Abra Info.plist: Vaya al archivo Info.plist de iOS de su proyecto Flutter (ubicado en ios/Runner/Info.plist).
  2. Añade la descripción de uso: Añade la clave NSUserTrackingUsageDescription con una explicación clara de por qué tu aplicación necesita el permiso de seguimiento.
Info.plist
<key>NSUserTrackingUsageDescription</key>
<string>This app uses tracking to provide personalized ads and improve your experience.</string>

Importante: La descripción de uso se mostrará a los usuarios en el aviso de ATT. Hágala clara, concisa y honesta sobre cómo el rastreo les beneficia.

Paso 2: Instalar el paquete de soporte de la ATT

Instale un paquete de soporte ATT de Flutter para habilitar la funcionalidad ATT en su aplicación. Recomendamos el plugin app_tracking_transparency.

Añadir dependencia

pubspec.yaml
dependencies:
  flutter:
    sdk: flutter
  singular_flutter_sdk: ^1.8.0
  app_tracking_transparency: ^2.0.4

Después de añadir la dependencia, ejecute flutter pub get para instalar el paquete.

bash
flutter pub get

Paquetes alternativos: Aunque recomendamos app_tracking_transparency, puedes utilizar cualquier plugin ATT de Flutter que ofrezca una funcionalidad similar. Asegúrate de que el plugin es compatible con iOS 14.5+.

Paso 3: Configurar el tiempo de espera del SDK

Configure el SDK Singular para esperar la respuesta ATT del usuario antes de inicializar estableciendo la propiedad waitForTrackingAuthorizationWithTimeoutInterval. Este retraso asegura que el IDFA es capturado si el usuario concede el permiso.

Crítico: Solicite siempre el consentimiento ATT y recupere el IDFA antes de que Singular SDK envíe su primera sesión. Si no lo hace, perderá permanentemente el IDFA para los datos de atribución de ese dispositivo.

Dart
import 'package:singular_flutter_sdk/singular_config.dart';

SingularConfig config = SingularConfig('API_KEY', 'SECRET');
config.waitForTrackingAuthorizationWithTimeoutInterval = 300; // Wait up to 5 minutes

Valor recomendado: Establezca el tiempo de espera en 300 segundos (5 minutos) si su aplicación muestra el mensaje ATT. Esto proporciona tiempo suficiente para que el usuario vea y responda al aviso sin crear una mala experiencia de usuario si el aviso se retrasa o no se muestra.

Paso 4: Solicitar el consentimiento ATT

Implemente el flujo de solicitud de ATT en su aplicación, solicitando a los usuarios el permiso de seguimiento en el momento adecuado de su experiencia de usuario.

Dart
import 'package:flutter/material.dart';
import 'dart:io';
import 'package:singular_flutter_sdk/singular.dart';
import 'package:singular_flutter_sdk/singular_config.dart';
import 'package:app_tracking_transparency/app_tracking_transparency.dart';

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

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  void initState() {
    super.initState();
    initializeApp();
  }

  Future<void> initializeApp() async {
    if (Platform.isIOS) {
      // Request ATT authorization
      final trackingStatus = await AppTrackingTransparency.requestTrackingAuthorization();

      // Log the user's response
      print('ATT Status: $trackingStatus');
      // Possible values: TrackingStatus.authorized, .denied, .restricted, .notDetermined
    }

    // Initialize Singular SDK (configured with wait timeout)
    SingularConfig config = SingularConfig('API_KEY', 'SECRET');
    config.waitForTrackingAuthorizationWithTimeoutInterval = 300;
    config.enableLogging = true;

    Singular.start(config);
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: MyHomePage(),
    );
  }
}

Comprender el flujo de la ATT

Cuando se establece un retardo de inicialización mediante waitForTrackingAuthorizationWithTimeoutInterval, el flujo de la aplicación funciona de la siguiente manera:

  1. Cuando se abre la aplicación, Singular SDK comienza a registrar una sesión y los eventos del usuario, pero aún no los envía al servidor de Singular.
  2. Cuando se concede/deniega el consentimiento de App Tracking Transparency, o transcurre el tiempo establecido, el SDK envía la sesión y cualquier evento en cola al servidor de Singular (con o sin el IDFA).
  3. Singular inicia entonces el proceso de atribución, aprovechando el IDFA si está disponible.

Escenarios ATT

La siguiente tabla resume los posibles escenarios de uso de esta integración:

Escenario Disponibilidad del IDFA
El usuario ve el diálogo de consentimiento y otorga su consentimiento antes de que transcurra el tiempo establecido. IDFA está disponible
El usuario ve el diálogo de consentimiento y lo deniega antes de que transcurra el tiempo establecido. IDFA no está disponible
El tiempo establecido expira, entonces el usuario ve el diálogo de consentimiento y otorga su consentimiento. IDFA está disponible sólo para los eventos de usuario que se reportan después de que se otorga el consentimiento
El tiempo establecido expira, entonces al usuario se le muestra el diálogo de consentimiento y niega el consentimiento. IDFA no está disponible
Al usuario se le muestra el diálogo de consentimiento, sale de la aplicación sin realizar ninguna acción, y más tarde abre la aplicación y concede el consentimiento después de que el tiempo establecido haya expirado. Los eventos en cola se envían al servidor Singular cuando se vuelve a abrir la aplicación. El IDFA no está disponible para estos eventos. Cualquier evento rastreado después de conceder el consentimiento sí tiene IDFA asociado.
Al usuario se le muestra el diálogo de consentimiento, sale de la aplicación sin realizar ninguna acción, y más tarde abre la aplicación y deniega el consentimiento. Los eventos en cola se envían a los servidores de Singular cuando se vuelve a abrir la aplicación. El IDFA no está disponible para estos eventos ni para ninguno de los eventos rastreados posteriormente.

Buenas prácticas de la ATT

  • Mensajes previos: Muestre a los usuarios una pantalla previa a la ATT en la que se explique por qué necesita el permiso de seguimiento y en qué les beneficia (mejores anuncios, mejor experiencia). Esto puede aumentar significativamente las tasas de aceptación.
  • El momento es importante: Muestre la solicitud de TCA en un momento natural del flujo de la aplicación, no inmediatamente después del lanzamiento. Deje que los usuarios experimenten primero su aplicación para generar confianza.
  • Configuración del tiempo de espera: Configure waitForTrackingAuthorizationWithTimeoutInterval entre 30 y 300 segundos. Una vez transcurrido el tiempo de espera, Singular procede con la atribución SKAN 4.0 (sin IDFA).
  • Realice pruebas exhaustivas: Pruebe tanto las situaciones autorizadas como las denegadas para asegurarse de que su aplicación funciona correctamente independientemente de la elección del usuario.
  • Respete la elección del usuario: Nunca preguntes repetidamente a los usuarios que han denegado el seguimiento ni muestres mensajes agresivos que les presionen para que acepten.
  • Gestión de errores: Compruebe el estado del seguimiento en restricted (por ejemplo, controles parentales) o en notDetermined y regístrelo para su análisis.
  • Integración de SKAN 4.0: Asegúrese de que las actualizaciones de los valores de conversión coinciden con el consentimiento de ATT para optimizar las devoluciones de SKAN (por ejemplo, utilice el panel de Singular para asignar eventos a los valores 0-63).

Revisión de App Store: Las aplicaciones que no implementen correctamente la ATT o que intenten eludir el marco pueden ser rechazadas durante la revisión de la App Store. Asegúrese de que su aplicación sigue las directrices de Apple y respeta las opciones de privacidad del usuario.

Recursos adicionales