apple-three-piece-analytics
Choose analytics and metrics sources for a solo / small-team Apple app and decide whether a third-party tracking SDK is justified. Use when picking an analytics SDK; when asked "should I add Firebase
SKILL.mdapple-dev-skills/skills/apple-three-piece-analytics/SKILL.md
GitHubApple Three-Piece Analytics
When to invoke
- 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 |
MetricKit, iOS / macOS 27+ (MetricManager().metricReports / .diagnosticReports, for await) |
Same coverage; MXMetricManager / MXMetricPayload / MXMetricManagerSubscriber are deprecated starting iOS / macOS 27 |
Same — catalog default is iOS 26, so no forced migration yet |
| Game Center (if it's a game) | Leaderboards / achievement completion / peer-player comparison | Game Center API / Game Center app |
macOS caveat: Apple's API lists
MXMetricManagerSubscriberon macOS 12 and later; which payloads a Mac actually delivers is not documented. Verify delivery on a device at your macOS floor, and fall back to App Store Connect Analytics + targetedOSSignpostertraces if payloads don't arrive.
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); otherwise Apple sends a missing-reason email, and since 2024-05-01 such uploads aren't accepted by App Store Connect (details inapp-store-review-rejections's privacy-manifest reference). 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 require ATT and only reads the IDFA if AdSupport is linked, 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 (iOS ≤ 26:
MXMetricManager.shared.add(...); iOS 27+:MetricManager()andfor awaitovermetricReports/diagnosticReports). - 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.- Official sources: when verifying or updating a factual or version-sensitive claim, read
references/official-docs.md.