Apple Three-Piece Analytics
When to invoke
- Starting a new App and deciding on an analytics SDK.
- Evaluating Firebase / TelemetryDeck / Mixpanel / Amplitude / Sentry.
- Writing
PrivacyInfo.xcprivacy. - User asks "what metrics should I track", "what can I see without a third-party SDK".
Scope
Owns the source-selection decision and its PrivacyInfo/ATT consequence. Does NOT own MetricKit wiring or payload interpretation → ios-performance-engineering; sink code → telemetry-facade-pattern; App Review privacy-label parity → app-store-review-rejections.
Default decisions
v1 uses the Apple three-piece set
| Source | What it provides | Where to view |
|---|---|---|
| App Store Connect Analytics | Downloads, sessions, active devices, retention, sources, store conversion | App Store Connect web |
MetricKit (MXMetricPayload, MXDiagnosticPayload) |
Performance & diagnostics: crash / hang / launch time / jank / energy / memory | The App receives them → persist to log / optionally upload later |
| Game Center (if it's a game) | Leaderboards / achievement completion / peer-player comparison | Game Center API / Game Center app |
macOS caveat: macOS 12–15 only send
MXDiagnosticPayload; macOS 26 and later send a dailyMXMetricPayloadjust like iOS. Only a deployment target below macOS 26 needs to fall back to App Store Connect Analytics + targetedOSSignpostertraces.
Privacy / Manifest
PrivacyInfo.xcprivacyis a required deliverable (hard App Store submission requirement since 2024-05-01 for any app using a required-reason API).- No third-party SDK doesn't mean a minimal manifest. The required-reason API rule applies to the App's own code, not just third-party SDKs: using
UserDefaults, file-modification timestamps, system boot time, disk-space APIs, or active-keyboards APIs each requires a declared entry inNSPrivacyAccessedAPITypes(e.g.UserDefaults→ reasonCA92.1) or ASC upload is rejected (ITMS-91053). Almost every app usesUserDefaults, so the manifest needs at least that entry plusNSPrivacyTracking: false. - No ATT prompt needed (no IDFA use case).
- CloudKit / Game Center's user-facing privacy notices are handled at the system layer by Apple; the App only needs to declare data usage in PrivacyInfo.
What's not covered (explicitly accepted)
- Micro-behaviour streams like "which button was tapped" or "how long was spent on a screen" are not covered by the three-piece set.
- Confirm v1 doesn't need to answer these questions; deviate if it does.
Rationale
- At solo / small-team scale, the three pieces cover most key questions (installs / retention / performance / crashes / player comparisons).
- No third-party SDK → no ATT, no extra tracking-domain disclosures, small build size, and the privacy claim is verifiable by readers via grep on
import. (The required-reason API entries above are still needed — they come from the App's own code, not a third-party SDK.) - Positive for a public-repo showcase ("no third-party tracking" is a credible commitment).
Deviation considerations
Adopt TelemetryDeck (privacy-friendly first)
- Trigger: actually need the micro-behaviour stream of "which button, where do users get stuck".
- Priority: TelemetryDeck > Firebase — Firebase does not access the IDFA and does not require ATT, and has shipped its own
PrivacyInfo.xcprivacysince 10.22.0 (2024-03); the reason to prefer TelemetryDeck is the smaller data-collection disclosure surface (tracking domains, more collected-data-type entries) and build size. - How to integrate: swap in the
TrackingSinkimplementation viatelemetry-facade-pattern; call sites change nothing.
Adopt Sentry / Crashlytics
- Trigger: MetricKit
MXDiagnosticPayloadpersistence still isn't enough for the incident workflow. - Cost: third-party SDK, extra PrivacyInfo entries, build size.
Verification checklist
PrivacyInfo.xcprivacyexists and passes App Store Connect validation.- No
import Firebase*/import Sentry/import Amplitude, etc. - MetricKit subscription is wired (
MXMetricManager.shared.add(...)). - Game Center entitlement aligns with leaderboard / achievement definitions (for games).
Related skills
telemetry-facade-pattern: the sink implementations for each piece.oslog-logger-defaults: MetricKit payloads persist via OSLog.apple-public-repo-security: "no PII / no third-party SDK" is one of the public-repo commitments.