Guide · iOS measurement
Your conversion value schema is a question. Most encode no question at all.
SKAdNetwork gives you a handful of bits to describe what a user did. Spend them on one decision you actually need to make, and iOS becomes measurable. Spend them on everything, and it does not.
The constraint, plainly
On iOS you do not get an event stream. You get a small number, once per install, within a measurement window, and only if the campaign passed Apple's anonymity threshold. Everything you will ever know about an iOS cohort has to fit inside that.
Which makes schema design a budgeting exercise. Every bucket you spend on something you will not act on is a bucket unavailable to the thing you will.
Start from the decision, not from the events
The wrong process is to list your in-app events and map them to values. The right one is to write down the decision the data has to support, then encode only what distinguishes the options.
For most subscription apps that decision is: which campaigns produce users who start a trial and stay long enough to convert. Which means the schema needs to separate no-trial from trial-started from trial-with-engagement, and almost nothing else.
| Value | Meaning | Why it earns a slot |
|---|---|---|
| 0 | Install, no meaningful activity | The baseline you are trying to buy less of |
| 1 | Onboarding completed | Separates real users from accidental installs |
| 2 | Reached the paywall | Distinguishes acquisition problems from paywall problems |
| 3 | Trial started | The primary optimisation event |
| 4 | Trial started, engaged in first 48h | Predicts trial-to-paid better than trial start alone |
| 5 | Paid within the window | Rare inside SKAN timing, but unambiguous when it happens |
Source: Illustrative structure, not a standard. The right schema depends on which decision your team actually makes with the data.
Why fewer buckets beat more
Apple withholds the conversion value entirely when a campaign has not cleared its privacy threshold. Fine-grained schemas split volume across many buckets, and thin buckets are exactly the ones most likely to come back null. You end up with an elaborate schema returning nothing.
The same logic pushes towards fewer, larger campaigns on iOS. This runs directly against good Android practice, where granularity helps, and it is the most common structural mistake we find in cross-platform accounts.
Timing beats richness
The measurement window is short relative to a subscription funnel. A schema that encodes day-14 retention will mostly encode nothing, because the postback fires first. Encode signals that occur inside the window and correlate with what you care about, rather than the thing you care about arriving too late to be seen.
Early engagement is the usual answer: whatever a user does in the first twenty-four to forty-eight hours that predicts trial-to-paid in your own historical data. That is a question your existing cohorts can answer before you write a single line of the schema.
Once it is live
Treat the schema as versioned infrastructure. Changing it invalidates comparisons with everything measured before, so change it deliberately, note the date, and expect a gap in your trend lines. Teams that quietly adjust it three times a quarter have no usable iOS history at all.
Questions people actually ask
- Do I still need SKAdNetwork if I have an MMP?
- Yes. Your MMP does not replace SKAdNetwork on iOS – it receives, decodes and organises the postbacks. The schema still has to be designed, and the MMP defaults are a starting point rather than an answer.
- How many conversion values should I use?
- As few as answer your question. The instinct is to encode everything the API allows; the result is a schema where every bucket has too little volume to be reliable. Six well-chosen values beat sixty-four thin ones.
- Revenue buckets or event sequence?
- Events for subscription apps, revenue for one-off purchases. Subscriptions produce almost no revenue inside the measurement window, so a revenue schema on a subscription app mostly encodes zero. Encode trial start and early retention instead.
- What changed with SKAN 4?
- Multiple postback windows rather than one, coarse-grained values as a lower-signal fallback, and hierarchical source identifiers that give more campaign granularity when volume permits. In practice it means you can measure a little further out, but the crowd-anonymity thresholds still decide how much you actually see.
- Why do postbacks arrive empty?
- Almost always privacy thresholds. Apple withholds the conversion value when a campaign has not passed its anonymity threshold, so low-volume campaigns return nulls. Fewer, larger campaigns produce more usable data than many small ones – which is the opposite of good Android practice.
We audit these for free.
Send us your schema and your campaign structure and we will tell you what your current setup can and cannot answer, and what we would change.