Skip to content

iOS Privacy and App Measurement

iOS 14.5 (released April 2021) introduced App Tracking Transparency (ATT), fundamentally changing how you measure app behavior on iOS. This framework restricts identifier access, limits conversion tracking, and forces marketers to adopt privacy-preserving measurement strategies.

For GA4 and app measurement, this means accepting reduced granularity in exchange for user trust. Understanding ATT, SKAdNetwork, and server-side measurement is essential for iOS app analytics in 2025.

App Tracking Transparency (ATT) framework overview

Section titled “App Tracking Transparency (ATT) framework overview”

ATT requires apps to request explicit user permission before accessing the device’s Identifier for Advertisers (IDFA). Without IDFA, cross-app user tracking and ad targeting become impossible.

  1. User opens your iOS app for the first time.
  2. App presents ATT permission dialog (controlled by your app, with a message you write).
  3. User chooses Allow (grant IDFA access) or Ask App Not to Track (deny IDFA access).
  4. If allowed, GA4 can use IDFA for cross-app tracking and audience syncing to Google Ads.
  5. If denied, GA4 falls back to fingerprinting via the advertising identifier and device signals.

Critical metric: Track opt-in rate. iOS apps typically see 20–40% ATT opt-in, with significant variation by audience and vertical.

// iOS Swift example: Request ATT permission
import AppTrackingTransparency
ATTrackingManager.requestTrackingAuthorization { status in
switch status {
case .authorized:
// IDFA is available; GA4 can use it for audience syncing
print("ATT authorized")
case .denied, .restricted:
// IDFA is not available; GA4 falls back to fingerprinting
print("ATT denied or restricted")
case .notDetermined:
// User hasn't responded yet
print("ATT pending")
@unknown default:
break
}
}
MetricWith IDFA (ATT Allowed)Without IDFA (ATT Denied)
User ID persistenceReliable (IDFA-based)Fingerprint-based (less reliable)
Cross-app trackingPossible (IDFA shared across apps)Not possible
Google Ads audience syncFull fidelityLimited; may exclude users
Conversion API matchingIDFA + email matchesEmail/phone only
Attribution window28 days (default)Limited by available signals
Data freshnessReal-time24–48 hour delay (privacy aggregation)

When a user denies ATT:

  1. GA4 generates a fingerprint based on device signals (OS version, language, IP, user agent)
  2. This fingerprint is less stable than IDFA (IP changes, browser data clears)
  3. GA4 cannot sync the user to Google Ads without additional identifiers (email, phone)
  4. Audiences built on ATT-denied users are smaller and less actionable

Recommendation: Always request ATT permission. Even if only 30% of users grant permission, you gain deterministic tracking for those users. The fingerprinting fallback is better than nothing but unreliable long-term.

Apple’s SKAdNetwork (SKAd) framework is Apple’s privacy-preserving alternative to IDFA-based ad attribution. It sits between your app, ad networks, and Apple’s attribution servers, aggregating conversion data without exposing individual users.

SKAdNetwork attributes installs and conversions within specific time windows. Apple sends postbacks (attribution reports) to your ad network 0–35 days after install, depending on conversion timing:

Postback WindowTimelineWhen to Expect Report
0–2 daysUser converts quickly24–48 hours after conversion
3–7 daysStandard attribution3–7 days after install
8–35 daysLong-tail conversions30–35 days after install

For example:

  • User installs app on March 1. Makes a purchase on March 1 (within 0–2 day window). You receive the attribution report by March 3.
  • User installs on March 1. Makes a purchase on March 10 (within 8–35 day window). You receive the report by March 35 (April 4).

Implication: Attribution data is delayed. You cannot optimize campaigns in real-time; you must use historical patterns and probabilistic models.

SKAdNetwork sends a conversion value (0–63, represented as 6 bits) to Apple’s attribution servers. This value encodes what happened post-install (purchase, signup, key event, etc.).

Example conversion value schema (you define this):

Value 0–10: Signup without purchase
Value 11–20: Purchase under $10
Value 21–30: Purchase $10–$50
Value 31–40: Purchase $50–$100
Value 41–50: Purchase $100–$500
Value 51–60: Purchase $500+
Value 61–63: Reserved for future use

When a user converts, your app must:

  1. Determine which bucket they fall into
  2. Call SKAdNetwork API with the corresponding conversion value
  3. Apple encrypts and aggregates the data
  4. Your ad network receives an attribution report with the conversion value

Challenge: With only 64 possible values, you must bucket conversions aggressively. You lose granularity (exact purchase amount, product category, etc.).

As of SKAdNetwork 4.0, Apple distinguishes between two types of conversion values:

Fine conversion values (6 bits, 64 possible values)

  • Full precision (0–63)
  • Sent within 0–2 day postback window only
  • Ad networks can see exact buckets
// Example: Fine conversion value for a $75 purchase
let conversionValue = SKAdNetwork.ConversionValue(35) // $50–$100 bucket
SKAdNetwork.updateConversionValue(conversionValue)

Coarse conversion values (2–3 bits, 4–8 possible values)

  • Lower granularity (Low, Medium, High, Very High)
  • Sent in all postback windows (0–2, 3–7, 8–35 days)
  • Grouped for privacy
// Example: Coarse conversion value for a high-value user
let coarseValue = SKAdNetwork.CoarseConversionValue.high
SKAdNetwork.updateConversionValue(
35,
coarseValue: coarseValue,
lockWindow: false
)

Recommendation: Use fine conversion values for 0–2 day window (e.g., immediate purchase). Use coarse values for 3+ day windows (e.g., app usage milestones) to protect user privacy.

Strategy 1: Hybrid measurement (GA4 + SKAdNetwork)

Section titled “Strategy 1: Hybrid measurement (GA4 + SKAdNetwork)”

Run GA4 for detailed behavioral analytics (user flow, engagement). Use SKAdNetwork for deterministic post-install attribution.

User journey:
1. Sees ad on Facebook/Google
2. Installs app
3. Opens app → GA4 measures session, page views, events
4. Makes purchase → SKAdNetwork converts to buckets, Apple sends postback
5. GA4 shows engagement path; SKAdNetwork shows install attribution

Advantage: Best of both worlds — detailed analytics + privacy-preserving attribution.

Strategy 2: Server-side conversion API matching

Section titled “Strategy 2: Server-side conversion API matching”

For users who grant IDFA access, send conversions server-side using email, phone, or hashed identifiers to Google Ads and Meta.

Conversion flow:
1. User converts in-app (purchase, signup)
2. Your app sends event to backend with user_id
3. Backend looks up user email/phone
4. Backend calls Google Conversion API with email hash + conversion data
5. Google matches hash to ad account and attributes conversion

Advantage: Attribution works without IDFA; your ad platforms get complete conversion data.

Strategy 3: Fingerprinting + cohort-based optimization

Section titled “Strategy 3: Fingerprinting + cohort-based optimization”

For ATT-denied users without IDFA, use cohort analysis to optimize campaigns without individual tracking.

Cohort-based optimization:
1. Segment users by first-week behavior (high engagement, low engagement, etc.)
2. Track cohort conversion rate, not individual conversions
3. Identify which ad audiences produce the highest-value cohorts
4. Reallocate budget to high-value-cohort audiences

Advantage: Works for all users, respects privacy, enables optimization at the segment level.

The gbraid parameter is Google’s privacy-preserving identifier for web attribution. While primarily for web, understanding it helps contextualize iOS measurement:

  • gbraid = Google Brand Identifier (encrypted, first-party only)
  • Used for web attributions without third-party cookies
  • Equivalent philosophy to SKAdNetwork for mobile: aggregate, privacy-first attribution

For iOS apps, Google Ads automatically injects gclid and gbraid into install campaigns. Your app receives these in deep links and should pass them to GA4:

// iOS: Capture Google Ads parameters from deep link
if let gclid = deepLinkParams["gclid"] {
Analytics.setUserProperty(gclid, forName: "gclid")
}
if let gbraid = deepLinkParams["gbraid"] {
Analytics.setUserProperty(gbraid, forName: "gbraid")
}
// GA4 will use these for cross-platform attribution

Server-side conversion API is the highest-fidelity approach for iOS measurement. Instead of relying on client-side identifiers, you send conversions directly from your backend to ad platforms.

  1. User converts in-app (purchase amount = $99, event = purchase).
  2. App sends event to your backend with user email/phone and conversion details.
  3. Backend calls Conversion API (Google Ads, Meta) with hashed email + conversion data.
  4. Ad platform matches hashed email to user account.
  5. Conversion is attributed to the install campaign (if within 28–30 day window).

Advantages:

  • Works without IDFA
  • Deterministic attribution (email is stable)
  • Highest conversion quality score

Challenges:

  • Requires backend infrastructure
  • PII handling and compliance (GDPR, CCPA)
  • API rate limits and quota management

Google’s Consent Mode v2 can work alongside iOS measurement, but with limitations:

Consent StateGA4 BehaviorAds Measurement
Consent grantedFull measurement; GA4 fires normallyGoogle Ads syncing enabled; conversions sent
Consent deniedMeasurement disabled; no events sent to GA4No Google Ads syncing; limited attribution
ATT allowed (IDFA)Measurement enabled; fingerprinting not neededFull Google Ads syncing possible
ATT denied (no IDFA)Fingerprint-based tracking; unreliableLimited Google Ads syncing

Best practice: Request ATT first, then Consent Mode. If user denies ATT, Consent Mode acceptance becomes less valuable because you lack deterministic identifiers anyway.

Best practices for maximizing data quality under ATT

Section titled “Best practices for maximizing data quality under ATT”

Show the ATT permission prompt on app launch, but only after explaining why you need the permission. Apps with a clear message see 30–50% ATT opt-in; apps with no context see 5–10%.

Example ATT message:
"We use your advertising ID to show you relevant ads and measure campaign performance.
Your data is never sold to third parties."

2. Implement conversion validation server-side

Section titled “2. Implement conversion validation server-side”

For purchases and key events, require server-side confirmation before marking conversion in GA4:

Client-side (unreliable):
1. User clicks "purchase"
2. App fires purchase event to GA4 immediately
3. If backend times out, conversion was recorded but order wasn't created
Server-side (reliable):
1. User clicks "purchase"
2. App sends order to backend
3. Backend creates order and returns confirmation
4. App fires purchase event to GA4 only after confirmation

Monitor the percentage of users who grant ATT permission. A declining opt-in rate signals that your ATT prompt isn’t compelling enough.

GA4 custom event:
Event: att_permission_response
Parameters:
- att_status: "allowed" | "denied"
- att_prompt_context: "launch" | "onboarding" | "settings"
- att_prompt_attempt_number: 1, 2, 3, ...

4. Use SKAdNetwork alongside GA4, not instead of

Section titled “4. Use SKAdNetwork alongside GA4, not instead of”

GA4 provides behavioral analytics (engagement, funnels, cohorts). SKAdNetwork provides install attribution. Use both:

  • GA4 for day-to-day analytics and product optimization
  • SKAdNetwork for campaign attribution and budget allocation

5. Build email/phone authentication into your app

Section titled “5. Build email/phone authentication into your app”

The most reliable identifier under ATT restrictions is email or phone number. Incentivize sign-up:

Benefit to user: "Sign in with email to sync your preferences across devices"
Benefit to you: Email enables server-side Conversion API attribution

If you store iOS user data, anonymize it quickly. Never retain IDFA longer than 30 days unless the user explicitly opts in.