Skip to content

feat(ios): send usage data to PostHog once the user opts in - #4058

Merged
datlechin merged 4 commits into
mainfrom
feat/ios-usage-data-default
Nov 5, 2026
Merged

datlechin merged 4 commits into
mainfrom
feat/ios-usage-data-default

Conversation

@datlechin

@datlechin datlechin commented Nov 5, 2026 •

Copy link
Copy Markdown
Member

Summary

  • iOS usage data goes to PostHog instead of the daily /v1/analytics report (tablepro-cloud docs/design/clients.md, iOS).
  • Still opt-in (App Review Guideline 5.1.1(ii), maintainer's call): nothing is sent until the user chooses Share Usage Data on the first-launch question or turns it on in Settings > Privacy. A device that opted in to the old report stays on; one that declined or never answered stays off, and a never-answered one gets the question.
  • The first-launch question and Settings footer list what PostHog receives, including the random ID and the IP-derived location.
  • Events: app_opened once per local day while the app is in front, with database types and connection count; connection_attempted, connection_succeeded, first_query_executed once per install with the database type. No identify, no person profiles.
  • The PostHog client and its config live in one file both apps compile. iOS also turns off surveys, push token registration and rage clicks.
  • Turning the switch off closes the SDK and a URL protocol refuses every PostHog request until it is on again. posthog-ios 3.92.7's optOut() stops captures but not uploads, so an event queued offline left after opt-out, on macOS too.
  • Only the Release configuration carries POSTHOG_PROJECT_KEY: Debug.xcconfig empties it, so local runs, tests, UI tests and previews of either app make no PostHog client, whatever Secrets.xcconfig sets.
  • First-use dates reuse the heartbeat's keys, so an updated device does not send them again.
  • PrivacyInfo.xcprivacy declares Device ID, Product Interaction, Other Usage Data, Coarse Location and Other Diagnostic Data: analytics, linked, not tracking.
  • Removes TableProCore's TableProAnalytics (only iOS used it), the AnalyticsHMACSecret plist key and ANALYTICS_HMAC_SECRET.
  • posthog-ios 3.92.7 joins the iOS project and its acknowledgements.
  • RELEASING.md iOS steps name POSTHOG_PROJECT_KEY and App Privacy.
  • Docs: docs(ios): opt-in usage data goes to PostHog docs#181.

Needs the maintainer

  • apple/Configs/Secrets.xcconfig on the Mac that archives the iOS app: POSTHOG_PROJECT_KEY = <the POSTHOG_PROJECT_KEY repository secret>. Without it the Release build sends nothing; Debug builds never read it.
  • App Store Connect > App Privacy for the new version, every type with purpose Analytics only, Linked to the user: Yes, Used for tracking: No:
    • Identifiers > Device ID
    • Usage Data > Product Interaction
    • Usage Data > Other Usage Data
    • Location > Coarse Location
    • Diagnostics > Other Diagnostic Data
  • No App Tracking Transparency prompt: nothing is combined with other companies' data or sent to a data broker.
  • Optional: PostHog project setting "Discard client IP data", so the raw IP is not stored (GeoIP still runs).

Test plan

  • TelemetryTests (new, iOS): an old opt-in stays on, declined or never answered makes no client, choosing Share starts sending, no key makes no client, turning off opts out, first use while off is not sent later, background launch sends no app_opened, once per day, once per install, heartbeat dates carry over, iOS SDK config, the transport gate, and the Debug build has no key.
  • debugBuildHasNoProjectKey on both apps reads the Debug test host's Info.plist. Before this change, the iOS Debug app built on a Mac whose Secrets.xcconfig has the key carried it; xcodebuild -showBuildSettings now resolves it empty for Debug and set for Release, on both projects.
  • verify.sh ios on TelemetryTests, OnboardingPreferencesTests, FirstRunPlanTests, AppStateLibraryTests, AcknowledgementsInventoryTests, ScenePresenterTests: 96 passed.
  • macOS TelemetryTests for the moved projectKey(from:).
  • check-license-inventory.py, localization.py extracted --target ios.

Screenshots

First-launch question, before (the daily report) and after (PostHog):

Before After
Before question light After question light
Before question dark After question dark

Settings > Privacy after Don't Share, before and after:

Before After
Before settings light After settings light
Before settings dark After settings dark

@datlechin
datlechin enabled auto-merge (squash) November 5, 2026 09:45
@datlechin
datlechin disabled auto-merge November 5, 2026 10:33
@datlechin
datlechin enabled auto-merge (squash) November 5, 2026 10:37
@datlechin
datlechin disabled auto-merge November 5, 2026 10:46
@datlechin datlechin changed the title feat(ios): send usage data to PostHog, on by default feat(ios): send usage data to PostHog once the user opts in Nov 5, 2026
@datlechin
datlechin enabled auto-merge (squash) November 5, 2026 10:51
@datlechin
datlechin merged commit 75ff628 into main Nov 5, 2026
10 of 11 checks passed
@datlechin
datlechin deleted the feat/ios-usage-data-default branch November 5, 2026 13:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant