iOS SDK
iOS SDK - Privacy & Consent
ATT helpers and GDPR / DMA consent for the Pricist iOS SDK.
The iOS SDK exposes two privacy primitives: App Tracking Transparency (ATT) helpers for Apple's IDFA prompt, and a setConsent API for GDPR / DMA. Both are opt-in — if you configure neither, the SDK tracks normally.
App Tracking Transparency (ATT)
Requesting authorization
requestTrackingAuthorization is a thin wrapper around ATTrackingManager.requestTrackingAuthorization. The SDK reads the resulting status itself — you do not need to pass it back:
import Pricist
Pricist.shared.requestTrackingAuthorization { status in
switch status {
case .authorized: print("ATT granted")
case .denied: print("ATT denied")
case .restricted: print("ATT restricted (parental controls)")
case .notDetermined: print("user dismissed without responding")
@unknown default: break
}
}Your Info.plist must contain an NSUserTrackingUsageDescription string. Without it, iOS will crash this call.
The live ATT status is attached to every event's context, so if the user changes the setting in iOS Settings later, subsequent events reflect the new value automatically.
Waiting for ATT before the first flush
The first events are the install / attribution signals — flushing them before the user has answered the ATT prompt means going out without IDFA, which weakens deterministic attribution. Set waitForATTAuthorization: true to defer the first flush:
let config = PricistConfiguration(sdkKey: "pk_live_…")
.with(waitForATTAuthorization: true)
Pricist.shared.initialize(with: config)
// later, e.g. after onboarding:
Pricist.shared.requestTrackingAuthorization { _ in
// SDK auto-resumes — events buffered while waiting flush now
}While waiting, trackEvent(...) calls are buffered in memory (not dropped), and no flush happens until ATT is answered.
GDPR / DMA consent
Pass a PricistConsent to record the user's decision. When GDPR applies and data-usage consent is denied, the SDK stops dispatching and purges its queue; otherwise consent rides along on each event's context:
Pricist.shared.setConsent(PricistConsent(
isUserSubjectToGDPR: true,
hasConsentForDataUsage: true
))The struct also accepts two ad-network signals that mirror Google Consent Mode v2 (ad_personalization and ad_storage). They are forwarded to ad networks but do not gate dispatch:
Pricist.shared.setConsent(PricistConsent(
isUserSubjectToGDPR: true,
hasConsentForDataUsage: true,
hasConsentForAdsPersonalization: false,
hasConsentForAdStorage: true
))| Field | Effect on the SDK |
|---|---|
isUserSubjectToGDPR | When false, the per-dimension flags are advisory and the SDK tracks normally. |
hasConsentForDataUsage | When false and isUserSubjectToGDPR == true, the SDK stops dispatching and purges its local queue. A nil value is treated as "not yet answered" and does not block dispatch. |
hasConsentForAdsPersonalization | Forwarded to ad networks (Google ad_personalization). Does not gate dispatch. |
hasConsentForAdStorage | Forwarded to ad networks (Google ad_storage). Does not gate dispatch. |
Consent revocation
When the user revokes consent (hasConsentForDataUsage: false with isUserSubjectToGDPR: true):
- New
trackEvent(...)calls are dropped. - Any pending events are purged from local storage.
- Requests already in flight will finish.
"Wait for everything" pattern (strict consent gate)
To make the SDK do nothing until the user accepts a consent banner, use autoStart: false. The SDK wires up internal state but performs no network activity until you call start():
let config = PricistConfiguration(sdkKey: "pk_live_…")
.with(autoStart: false)
Pricist.shared.initialize(with: config)
// after the user accepts your banner:
Pricist.shared.setConsent(PricistConsent(
isUserSubjectToGDPR: true,
hasConsentForDataUsage: true
))
Pricist.shared.start()