SDK de iOS - Privacidad de datos

Cumplimiento de las leyes de privacidad de datos

Implemente la recolección de datos conforme a la privacidad notificando a Singular las elecciones de consentimiento del usuario para GDPR, CCPA y otras regulaciones de privacidad del consumidor.

Cuando los usuarios consientan o se nieguen a compartir su información con terceros, utilice los métodos de privacidad de Singular para comunicar su elección. Esto garantiza el cumplimiento de regulaciones como la California Consumer Privacy Act (CCPA) y permite que los partners respeten las preferencias de privacidad del usuario.

Más información: Consulte Privacidad del usuario y limitación del intercambio de datos para obtener información detallada sobre cómo Singular procesa el consentimiento de privacidad.


Limitar el intercambio de datos

Controlar el intercambio de datos con terceros

Notifique a Singular si los usuarios han consentido en compartir sus datos personales con partners externos utilizando el método limitDataSharing .

Firma del método:

+ (void)limitDataSharing:(BOOL)shouldLimitDataSharing;

Parámetros:

  • NO (false): El usuario ha optado por participar y ha consentido en compartir sus datos
  • YES (true): El usuario ha optado por no participar y no consiente en compartir sus datos

Importante: Aunque es opcional, este método afecta al intercambio de datos de atribución. Algunos partners solo comparten información de atribución completa cuando se les notifica explícitamente que los usuarios han optado por participar.

Ejemplos de uso

Swift Objective-C
// User has opted in to share their data
Singular.limitDataSharing(false)

// User has opted out and declined to share their data
Singular.limitDataSharing(true)

// Example: Set based on user preference
func handlePrivacyConsent(userConsented: Bool) {
    // Pass inverse: false = opted in, true = opted out
    Singular.limitDataSharing(!userConsented)

    print("Data sharing: \(userConsented ? "Enabled" : "Limited")")
}

Cómo funciona:

Singular utiliza esta configuración en postbacks de privacidad del usuario y la transmite a los partners que la requieren para el cumplimiento normativo.


Limitación del intercambio de datos por evento

Anular el intercambio de datos en un único evento

Puede anular la configuración global de limitDataSharing para un único evento o llamada de ingreso personalizado pasando el atributo ATTRIBUTE_SNG_LIMIT_DATA_SHARING junto con los demás argumentos del evento. Esto es útil cuando un usuario actualiza su consentimiento de manera simultánea a una acción y desea que ese evento específico refleje la nueva elección de inmediato, sin cambiar la configuración global del SDK para los eventos siguientes.

Valores aceptados:

  • NO (false): El usuario ha optado por participar solo para este evento
  • YES (true): El usuario ha optado por no participar solo para este evento

Importante: El atributo debe ser un valor booleano ( BOOL en Objective-C, Bool en Swift). Las entradas que no sean booleanas se ignoran y la solicitud recurre a la configuración global de limitDataSharing . En cualquier caso, el atributo se elimina de los argumentos del evento antes de enviar la solicitud, por lo que nunca aparece en la carga útil del evento.

Ejemplos de uso

Swift Objective-C
// Example 1: Standard event, opt out only for this event
var dic: [AnyHashable: Any] = [:]
dic[ATTRIBUTE_SNG_LIMIT_DATA_SHARING] = true
dic["order_id"] = "12345"

Singular.event("checkout_completed", withArgs: dic)

// Example 2: Custom revenue, opt in only for this event
var attributes: [AnyHashable: Any] = [:]
attributes[ATTRIBUTE_SNG_LIMIT_DATA_SHARING] = false
attributes["sku"] = "premium_monthly"

Singular.customRevenue("premium_purchase",
                      currency: "USD",
                      amount: 9.99,
                      withAttributes: attributes)

Cómo funciona:

Cuando se proporciona un valor booleano válido, el SDK elimina el atributo de los argumentos del evento y lo escribe en el campo data_sharing_options.limit_data_sharing de la solicitud, anulando la configuración global de limitDataSharing solo para esa solicitud. La configuración global y el resultado de getLimitDataSharing no se modifican, por lo que los eventos posteriores que no proporcionen el atributo seguirán utilizando la elección global.


Métodos de cumplimiento del GDPR

Gestione el consentimiento de seguimiento del usuario y controle la funcionalidad del SDK para cumplir con el GDPR (Reglamento General de Protección de Datos) y otras regulaciones de privacidad.

Gestión del consentimiento de seguimiento

trackingOptIn

Registre el consentimiento explícito del usuario para el seguimiento enviando un evento de opt-in del GDPR a los servidores de Singular.

Requisito previo de Info.plist: Si su app utiliza el App Tracking Transparency de Apple (iOS 14.5+) — necesario para acceder al IDFA en los usuarios que dan consentimiento — declare NSUserTrackingUsageDescription en su Info.plist con una explicación clara y orientada al usuario antes de mostrar el aviso de ATT o llamar a +trackingOptIn . Las apps que solicitan seguimiento sin esta clave son rechazadas en App Review.

Firma del método:

+ (void)trackingOptIn;

Cuándo utilizarlo:

  • Cumplimiento del GDPR: Llamar cuando los usuarios consientan explícitamente al seguimiento en regiones reguladas por el GDPR
  • Registro de consentimiento: Marca a los usuarios como proveedores del consentimiento del GDPR en los sistemas de Singular
  • Comportamiento por defecto: Sin esta llamada, el SDK continúa con el seguimiento, pero no registra específicamente el consentimiento
Swift Objective-C
// User accepted tracking consent
Singular.trackingOptIn()

// Example: Call after consent dialog
func onUserAcceptedTracking() {
    Singular.trackingOptIn()
    print("User opted in to tracking")
}

Métodos de control del seguimiento

stopAllTracking

Desactive por completo todas las actividades de seguimiento del SDK para el usuario actual en este dispositivo.

Firma del método:

+ (void)stopAllTracking;

Advertencia crítica: Este método desactiva el SDK de forma permanente hasta que se llame a resumeAllTracking . El estado desactivado persiste tras los reinicios de la app y solo se puede revertir mediante programación.

Comportamiento:

  • Efecto inmediato: Detiene todo el seguimiento, el reporte de eventos y la recolección de datos al instante
  • Estado persistente: Permanece desactivado incluso después de cerrar y reabrir la app
  • Sin reinicio automático: Debe llamar explícitamente a resumeAllTracking para volver a activarlo
Swift Objective-C
// User declined all tracking
Singular.stopAllTracking()

// Example: Handle user opt-out
func onUserDeclinedTracking() {
    Singular.stopAllTracking()
    print("All tracking stopped")

    // Optionally store preference
    saveUserTrackingPreference(false)
}

resumeAllTracking

Vuelva a activar el seguimiento después de detenerlo con stopAllTracking .

Firma del método:

+ (void)resumeAllTracking;

Casos de uso:

  • Cambio de consentimiento: El usuario cambia sus preferencias de privacidad y vuelve a aceptar el seguimiento
  • Ajustes de privacidad: El usuario actualiza el consentimiento desde el menú de configuración de la app
  • Cumplimiento regional: Reactivar el seguimiento cuando el usuario se traslada a regiones no reguladas
Swift Objective-C
// User opted back in to tracking
Singular.resumeAllTracking()

// Example: Handle consent update
func onUserResumedTracking() {
    Singular.resumeAllTracking()
    print("Tracking resumed")

    // Optionally update stored preference
    saveUserTrackingPreference(true)
}

isAllTrackingStopped

Compruebe si el seguimiento ha sido desactivado para el usuario actual.

Firma del método:

+ (BOOL)isAllTrackingStopped;

Devuelve:

  • YES (true): El seguimiento está actualmente detenido mediante stopAllTracking
  • NO (false): El seguimiento está activo (nunca se detuvo o se reanudó)

Devuelve NO si el SDK no se ha inicializado, independientemente del estado de seguimiento anterior. Confirme siempre que +start: se haya completado antes de basarse en este valor, e interprete NO como "no detenido o aún no inicializado" en lugar de "haciendo seguimiento activamente".

Swift Objective-C
// Check current tracking status
let isTrackingStopped = Singular.isAllTrackingStopped()

// Example: Display privacy status in settings
func getPrivacyStatusText() -> String {
    return Singular.isAllTrackingStopped() ? "Tracking: Disabled" : "Tracking: Enabled"
}

// Example: Sync UI with tracking state
func updatePrivacyToggle() {
    let isStopped = Singular.isAllTrackingStopped()
    privacyToggle.isOn = !isStopped
    print("Current tracking state: \(isStopped ? "Stopped" : "Active")")
}

Protección de la privacidad infantil

trackingUnder13

Notifique a Singular que el usuario es menor de 13 años para cumplir con la COPPA (Ley de Protección de la Privacidad Infantil en Línea) y otras regulaciones de privacidad infantil.

Firma del método:

+ (void)trackingUnder13;

Requisitos de cumplimiento:

  • Cumplimiento de la COPPA: Necesario para apps que recopilan datos de niños menores de 13 años en Estados Unidos
  • Contenido con restricción de edad: Utilícelo cuando los usuarios se identifiquen como menores de 13 años durante el registro o la verificación de edad
  • Seguimiento restringido: Limita la recopilación de datos para cumplir con las leyes de protección de la privacidad infantil
Swift Objective-C
// User identified as under 13
Singular.trackingUnder13()

// Example: Call after age verification
func onAgeVerified(userAge: Int) {
    if userAge < 13 {
        Singular.trackingUnder13()
        print("COPPA mode enabled for user under 13")
    }
}

Importante: Llame a este método lo antes posible después de determinar que el usuario es menor de 13 años, idealmente durante la inicialización de la app o inmediatamente después de la verificación de edad. Esto garantiza que todo el seguimiento posterior respete las regulaciones de privacidad infantil.


limitAdvertisingIdentifiers

Restrinja la recopilación y el uso de identificadores publicitarios (IDFA en iOS) durante la inicialización del SDK para apps de audiencia mixta.

Propiedad de configuración:

@property (assign) BOOL limitAdvertisingIdentifiers;

Casos de uso:

  • Apps de audiencia mixta: Apps que atienden tanto a adultos como a niños cuando se determina la edad antes del lanzamiento
  • Usuarios COPPA conocidos: Cuando se sabe en el momento de la inicialización que el usuario es menor de 13 años
  • Enfoque de privacidad primero: Aplicar limitaciones a los identificadores publicitarios desde la primera sesión del SDK

Método de configuración

Establezca las limitaciones de identificadores publicitarios durante la inicialización del SDK para apps que conozcan los requisitos de privacidad de antemano.

Swift Objective-C
// Limit advertising identifiers at initialization
let config = SingularConfig(apiKey: "SDK_KEY", andSecret: "SDK_SECRET")
config?.limitAdvertisingIdentifiers = true

Singular.start(config)

Build del Kids SDK: limitAdvertisingIdentifiers se excluye de la compilación en el build del Singular Kids SDK (protegido por #ifndef SINGULAR_KIDS ). Si está integrando Singular-Kids-SDK , esta propiedad no está disponible — el Kids SDK aplica automáticamente un manejo más estricto de los identificadores. Para el marcado de COPPA en tiempo de ejecución, utilice trackingUnder13 .

Método en tiempo de ejecución

Active o desactive la recopilación de identificadores publicitarios en cualquier momento después de +start: . Es útil para apps de audiencia mixta en las que la verificación de edad, el aviso de consentimiento o la selección de contenido se produce después de que el SDK ya se ha iniciado.

+ (void)setLimitAdvertisingIdentifiers:(BOOL)enabled;
Swift Objective-C
// Apply identifier limit after the user enters kids mode
func onKidsModeSwitched(isKidsMode: Bool) {
    Singular.setLimitAdvertisingIdentifiers(isKidsMode)
}

El método en tiempo de ejecución también requiere un argumento BOOL — llamar a +setLimitAdvertisingIdentifiers sin argumentos no compilará. Al igual que la propiedad en tiempo de configuración, este método no está disponible en el build del Kids SDK.

Mejor práctica: Para un cumplimiento integral de la COPPA, utilice limitAdvertisingIdentifiers durante la inicialización y llame a trackingUnder13() cuando se verifique la edad del usuario. Esto garantiza una protección completa desde la primera sesión.


Mejores prácticas de implementación

Ejemplo completo de gestión de la privacidad

Implemente controles de privacidad integrales que respeten las preferencias del usuario y cumplan con las regulaciones.

Swift Objective-C
import Foundation

class PrivacyManager {

    private let userDefaults = UserDefaults.standard
    private let consentKey = "user_consent"
    private let dataSharingKey = "data_sharing"

    // Initialize privacy settings on app start
    func initializePrivacy() {
        let hasUserConsent = getUserConsent()
        let allowDataSharing = getDataSharingPreference()

        // Apply stored preferences
        if hasUserConsent {
            Singular.trackingOptIn()
            Singular.resumeAllTracking()
        } else {
            Singular.stopAllTracking()
        }

        // Set data sharing preference
        Singular.limitDataSharing(!allowDataSharing)

        print("Privacy initialized: consent=\(hasUserConsent), sharing=\(allowDataSharing)")
    }

    // User accepts tracking via consent dialog
    func userAcceptedTracking() {
        saveUserConsent(true)
        Singular.trackingOptIn()
        Singular.resumeAllTracking()
        print("User accepted tracking")
    }

    // User declines tracking
    func userDeclinedTracking() {
        saveUserConsent(false)
        Singular.stopAllTracking()
        print("User declined tracking")
    }

    // User updates data sharing preference
    func setDataSharingEnabled(_ enabled: Bool) {
        saveDataSharingPreference(enabled)
        // Note: limitDataSharing uses inverse logic
        Singular.limitDataSharing(!enabled)
        print("Data sharing: \(enabled ? "Enabled" : "Limited")")
    }

    // Get current tracking status
    func isTrackingEnabled() -> Bool {
        return !Singular.isAllTrackingStopped()
    }

    // Private helper methods
    private func getUserConsent() -> Bool {
        return userDefaults.bool(forKey: consentKey)
    }

    private func saveUserConsent(_ consent: Bool) {
        userDefaults.set(consent, forKey: consentKey)
    }

    private func getDataSharingPreference() -> Bool {
        return userDefaults.bool(forKey: dataSharingKey)
    }

    private func saveDataSharingPreference(_ enabled: Bool) {
        userDefaults.set(enabled, forKey: dataSharingKey)
    }
}

Mejores prácticas:

  • Almacenamiento persistente: Guarde las preferencias del usuario en UserDefaults o almacenamiento seguro
  • Inicialización temprana: Aplique los ajustes de privacidad antes de la inicialización del SDK siempre que sea posible
  • Sincronización de la UI: Mantenga la UI de configuración sincronizada con el estado real del SDK utilizando isAllTrackingStopped
  • Comunicación clara: Proporcione controles de privacidad claros y accesibles en los ajustes de la app
  • Documentación de cumplimiento: Mantenga registros claros de la implementación de privacidad para auditorías regulatorias