Lavorare con ATT (App Tracking Transparency) su iOS
ATT e la gestione dei consensi sono sistemi separati che devi coordinare manualmente.
Questa guida spiega come integrare correttamente il framework App Tracking Transparency (ATT) di Apple con il nostro SDK CMP. L'ATT è un requisito a livello di piattaforma (Apple), mentre il CMP gestisce il consenso legale/normativo. Entrambi devono funzionare insieme per garantire la conformità e il corretto funzionamento dell'SDK.
Il prompt iOS App Tracking Transparency (ATT) e la gestione del consenso ai sensi del GDPR/ePrivacy
serve different purposese operare
independently. Ti consigliamo di verificare che
no SDK whatsoeverè caricata
beforela finestra di dialogo ATT
and beforeil nostro SDK. In base alle scelte effettuate dall'utente su
bothla finestra di dialogo ATT e il nostro livello di consenso, caricare o meno gli SDK specificati.
Per chiarire:
-
La finestra di dialogo ATT e il consent layer (CMP) riguardano basi giuridiche e ambiti diversi.
-
L'ATT è il meccanismo di Apple per ottenere il permesso dell'utente per il tracciamento tra app (ovvero la condivisione di identificatori come l'IDFA con terze parti a fini pubblicitari).
-
Il consent layer (CMP) regola l'utilizzo dei cookie e degli SDK per scopi quali analisi, personalizzazione, misurazione o funzioni essenziali dell'app — come richiesto dal GDPR/ePrivacy e da leggi simili. Come esempi, possiamo citare Firebase (GFA), Crashlytics, OneSignal, MixPanel, Sentry, ecc. Nessuno di questi è direttamente correlato all'ATT, ma è comunque necessario ottenere il consenso dell'utente.
-
Anche se un utente seleziona "Chiedi all'app di non tracciare" a livello di sistema su iOS, la tua app potrebbe comunque elaborare determinati tipi di dati (ad esempio, cookie funzionali, SDK di misurazione o altri strumenti tecnici) che richiedono una base giuridica o il consenso ai sensi delle leggi sulla privacy. Pertanto, il livello di consenso deve comunque essere visualizzato, in modo che l'utente possa esercitare la propria scelta riguardo a queste tecnologie. Assicurati che questo non sia il tuo caso, poiché se decidi di impedire la visualizzazione del livello di consenso ma continui a caricare qualsiasi SDK che gestisce i dati verso i server dal dispositivo, anche con scopi/fornitori diversi, la tua app verrà bloccata.
Fase 1: Prerequisiti
-
Versione minima di iOS: iOS 14 (ATT non disponibile nelle versioni precedenti)
-
Aggiungi AppTrackingTransparency.framework al tuo progetto
-
Nel tuo Info.plist, aggiungi:
<key>NSUserTrackingUsageDescription</key>
<string>This identifier will be used to deliver personalized ads and improve user experience.</string>
-
La stringa deve spiegare chiaramente perché richiedi il tracciamento
Apple potrebbe rifiutare formulazioni vaghe.
Tutta la gestione dell'ATT deve avvenire all'interno dell'app mobile stessa e non tramite il nostro SDK, poiché il nostro SDK non è a conoscenza del ciclo di vita dell'app mobile che lo integra. La richiesta di ATT deve essere visualizzata e gestita completamente prima del nostro SDK, e la finestra di dialogo dell'ATT non deve essere caricata contemporaneamente o sopra il nostro livello di consenso. Assicurati di caricare il nostro livello di consenso solo tramite checkAndOpen() o forceOpen() dopo aver gestito la richiesta ATT e aver verificato che la scelta dell'utente relativa all'ATT sia già stata aggiornata sul dispositivo. Non caricare il nostro livello di consenso prima di ciò.
Fase 2: Verifica lo stato ATT
Verifica lo stato attuale dell'autorizzazione ATT prima di inizializzare gli SDK di tracciamento:
import AppTrackingTransparency
import AdSupport
if #available(iOS 14, *) {
let status = ATTrackingManager.trackingAuthorizationStatus
switch status {
case .authorized:
// IDFA available
case .denied, .restricted:
// IDFA blocked
case .notDetermined:
// Prompt will be shown later
@unknown default:
break
}
}
Fase 3: Richiedi l'autorizzazione ATT
Se lo stato è .notDetermined, richiedi l'autorizzazione quando l'app è attiva:
if #available(iOS 14, *) {
ATTrackingManager.requestTrackingAuthorization { status in
DispatchQueue.main.async {
self.didReceiveATTStatus(status)
}
}
} else {
// iOS < 14: proceed to CMP directly
openCMP()
}
Fase 4: Gestire i risultati ATT
Definisci come elaborare il risultato dell'ATT e poi avvia il CMP:
func didReceiveATTStatus(_ status: ATTrackingManager.AuthorizationStatus) {
switch status {
case .authorized:
openCMP()
case .denied, .restricted:
rejectAdPurposesAndVendors {
self.openCMP()
}
case .notDetermined:
openCMP()
@unknown default:
openCMP()
}
}
Fase 5: Lancia CMP
Una volta risolto l'ATT, determinare lo stato dell'ATT nell'interfaccia utente del CMP per poter aprire l'interfaccia utente del CMP e raccogliere il consenso legale/normativo utilizzando un design mirato:
private func openCMP() {
CMPManager.shared.setATTStatus = // insert here the ATT status retrieved
//from ATTManager.AuthorizationStatus
CMPManager.shared.checkAndOpen()
}
Fase 6: Tabella decisionale — ATT × Comportamento CMP × Azioni SDK
| Stato ATT | IDFA | Comportamento CMP | Azioni SDK |
|---|---|---|---|
.notDetermined |
No | Attendere la richiesta di autorizzazione ATT, quindi avviare CMP. | Non inizializzare ancora i tracker. |
.authorized |
Sì | Raccogliere il consenso CMP granulare. | Abilitare pubblicità/analisi solo se consentito da CMP. |
.denied |
No | Considerare la pubblicità e la profilazione come rifiutate. | Rifiutare programmaticamente gli scopi pubblicitari e i fornitori, quindi mostrare il CMP per scopi non di tracciamento. |
.restricted |
No | Come "Rifiutato". | Rifiuta scopi pubblicitari/fornitori, quindi apri il CMP. |
| iOS < 14 | N/A | Ignora ATT, usa solo CMP. | Bloccare fino a quando il CMP non risolve. |
Passaggio 7: Ricette API compatibili con ATT
Rifiuta gli scopi pubblicitari/i fornitori quando l'ATT è negato o limitato
func rejectAdPurposesAndVendors(completion: @escaping () -> Void) {
let adPurposeIds = ["c52", "c53"] // Example purposes
CMPManager.shared.rejectPurposes(adPurposeIds, updateVendor: true)
}
(OPPURE) Finalità pubblicitarie/fornitori pre-concessione quando autorizzato da ATT
func pregrantAdPurposesAndVendorsThenOpenCMP() {
let adPurposeIds = ["c52", "c53"]
CMPManager.shared.acceptPurposes(adPurposeIds, updatePurpose: true)
}
Passaggio 8: ricontrolla su App Resume
L'ATT può essere modificato nelle Impostazioni. Ricontrolla sempre al termine:
Passaggio 9: Casi limite e soluzioni di ripiego
-
Limitato: ATT non disponibile (ad es. controllo genitori). Blocca tracciamento.
-
iOS < 14: No ATT → usa solo CMP.
-
Prompt non disponibile: l'ATT deve essere richiesto quando l'app è attiva.
-
Rifiuto da parte dell'utente: considera gli scopi pubblicitari/i fornitori come rifiutati.
Fase 10: Test e debug
-
Utilizza un'installazione nuova per attivare la finestra di dialogo ATT.
-
Verifica tutte le condizioni:
.authorized,.denied,.restricted,.notDetermined. -
Attiva/disattiva l'ATT in Simulatore/Dispositivo fisico in Impostazioni → Privacy e sicurezza → Tracciamento.
-
Registra gli output per confermare che il CMP venga avviato solo dopo la risoluzione dell'ATT.
Passo 11: Best practice
- Non inizializzare mai i tracker prima che il flusso ATT + CMP sia terminato.
- Usa i suggerimenti in modo saggio; non indurre mai in errore gli utenti, poiché ciò potrebbe portare al blocco.
- Non sovrapporre l'interfaccia utente di CMP alla finestra di dialogo di ATT.
- Consenti agli utenti di riaprire il CMP in qualsiasi momento.
- Aspettati un rifiuto da parte di Apple Review se il tracciamento avviene prima dell'autorizzazione ATT.
Fase 12: Lista di controllo per gli sviluppatori
-
Aggiungi
AppTrackingTransparency.framework. -
Aggiungi
NSUserTrackingUsageDescriptiona Info.plist. -
Verifica lo stato di ATT all'avvio.
-
Mostra il suggerimento, se lo desideri.
-
Richiedi ATT se
.notDetermined. -
Gestisci i risultati dell'ATT (accetta/rifiuta fornitori/finalità di conseguenza).
-
Avvia CMP dopo il completamento di ATT.
-
Inizializza/blocca gli SDK solo dopo che il CMP è stato risolto.
-
Ricontrolla l'ATT sul riassunto dell'app.
-
Fornisci l'opzione di riapertura del CMP.
-
Verifica tutti i flussi.