Skip to content

chore: deprecate PostHogDataMode.cellular - #891

Merged
turnipdabeets merged 2 commits into
mainfrom
chore/deprecate-datamode-cellular
Oct 5, 2026
Merged

turnipdabeets merged 2 commits into
mainfrom
chore/deprecate-datamode-cellular

Conversation

@turnipdabeets

Copy link
Copy Markdown
Contributor

💡 Motivation and Context

PostHogDataMode.cellular has never done anything different from .any, so this deprecates it ahead of removing it in 4.0.

  • dataMode is only read in PostHogQueue.updatePauseState. The queue pauses when there is no connection, or when dataMode == .wifi and the device isn't on Wi-Fi. Every other case sends, so .cellular falls through exactly like .any.
  • That's been true since the v3 rewrite (iOS SDK v3 #75, Nov 2023). The 2.x Objective-C SDK had no data mode at all. The doc comment already says it behaves like .any.
  • No other PostHog SDK (Android, React Native, KMP) has a data-mode setting, and no sdk-specs spec covers it.
  • The name suggests "send only on cellular", which it never did. posthog-flutter's Dart doc even says "Send data only on cellular connections".

Nothing changes at runtime. Anyone using .cellular can switch to .any and get identical behavior.

Migration: replace .cellular with .any (PostHogDataModeCellular with PostHogDataModeAny in Objective-C).

Changes:

  • @available(*, deprecated, ...) on PostHogDataMode.cellular, with a message pointing to .any.
  • Doc comments on the case and on PostHogConfig.dataMode updated to match.
  • Changeset: posthog-ios minor.

Notes:

  • The SDK never references PostHogDataMode.cellular, so the attribute adds no warnings to the SDK build. Reachability.Connection.cellular and $network_cellular are separate and untouched.
  • Swift callers get a deprecation warning. Objective-C callers don't, because Swift doesn't put availability attributes on @objc enum cases in the generated header (PostHogDataModeCellular = 1 is emitted with no deprecation macro). The header still carries the updated doc comment.
  • The public API snapshot doesn't change, because it doesn't record availability attributes.

posthog-flutter follow-up: posthog-flutter exposes PostHogDataMode { wifi, cellular, any } (Apple only), and its plugin maps "cellular" to config.dataMode = .cellular in PosthogFlutterPlugin.swift. That line will produce a deprecation warning once posthog-flutter picks up this release. The fix is to map "cellular" to .any in the plugin, which keeps the Dart API unchanged (no breaking change for Flutter), and to correct the Dart doc comment. That goes in a separate posthog-flutter PR.

💚 How did you test it?

  • make test: passed (XCTest: 174 tests, 0 failures; Swift Testing: 919 tests in 148 suites)
  • make buildSdk: succeeded for iOS, macOS, tvOS, watchOS and visionOS, with no new warnings
  • make apiCheck: snapshot up to date (no diff).
  • Built the PostHog scheme for iOS and checked the generated PostHog-Swift.h: PostHogDataModeWifi = 0, PostHogDataModeCellular = 1, PostHogDataModeAny = 2, and no new warnings from PostHog/ sources.
  • No new test. This only adds an attribute, and there is no behavior to test beyond the existing dataMode default check in PostHogConfigTest.

📝 Checklist

  • I reviewed the submitted code.
  • I added tests to verify the changes.
  • I updated the docs if needed.
  • No breaking change or entry added to the changelog.

If releasing new changes

  • Ran pnpm changeset to generate a changeset file

🤖 Agent context

Autonomy: Human-driven (agent-assisted)

Claude Code made the change, ran make format, make test, make buildSdk and make apiCheck, and checked the generated Objective-C header. The deprecation message follows the existing "This will be removed in the next major version." wording used elsewhere in the SDK. The removal for 4.0 is a separate PR on the 4.0 stack.

🤖 Generated with Claude Code

PostHogDataMode.cellular has always behaved the same as .any: the queue
only pauses when there is no connection, or when dataMode is .wifi and
the device isn't on Wi-Fi. Deprecate it in favor of .any ahead of its
removal in 4.0. The SDK never references it, so this adds no warnings
to the SDK build.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@turnipdabeets
turnipdabeets requested a review from a team as a code owner October 1, 2026 19:31
@github-actions

github-actions Bot commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

posthog-ios Compliance Report

Date: 2026-10-01 23:13:51 UTC
Duration: 229927ms

⚠️ Some Tests Failed

44/45 tests passed, 1 failed


Capture Tests

⚠️ 28/29 tests passed, 1 failed

View Details
Test Status Duration
Format Validation.Event Has Required Fields ✅ 2942ms
Format Validation.Event Has Uuid ✅ 3062ms
Format Validation.Event Has Lib Properties ✅ 494ms
Format Validation.Distinct Id Is String ✅ 667ms
Format Validation.Token Is Present ✅ 3024ms
Format Validation.Custom Properties Preserved ✅ 2962ms
Format Validation.Event Has Timestamp ✅ 2995ms
Retry Behavior.Retries On 503 ✅ 11837ms
Retry Behavior.Does Not Retry On 400 ✅ 4966ms
Retry Behavior.Does Not Retry On 401 ✅ 4960ms
Retry Behavior.Respects Retry After Header ✅ 7778ms
Retry Behavior.Implements Backoff ✅ 15439ms
Retry Behavior.Retries On 500 ✅ 9254ms
Retry Behavior.Retries On 502 ✅ 9447ms
Retry Behavior.Retries On 504 ✅ 5696ms
Retry Behavior.Max Retries Respected ❌ 21729ms
Deduplication.Generates Unique Uuids ✅ 3303ms
Deduplication.Preserves Uuid On Retry ✅ 9292ms
Deduplication.Preserves Uuid And Timestamp On Retry ✅ 16721ms
Deduplication.Preserves Uuid And Timestamp On Batch Retry ✅ 8115ms
Deduplication.No Duplicate Events In Batch ✅ 3189ms
Deduplication.Different Events Have Different Uuids ✅ 3199ms
Compression.Sends Gzip When Enabled ✅ 2900ms
Batch Format.Uses Proper Batch Structure ✅ 2903ms
Batch Format.Flush With No Events Sends Nothing ✅ 432ms
Batch Format.Multiple Events Batched Together ✅ 3164ms
Error Handling.Does Not Retry On 403 ✅ 5015ms
Error Handling.Does Not Retry On 413 ✅ 5088ms
Error Handling.Retries On 408 ✅ 9371ms

Failures

retry_behavior.max_retries_respected

Expected 4 requests, got 6

Feature_Flags Tests

✅ 16/16 tests passed

View Details
Test Status Duration
Request Payload.Request With Person Properties Device Id ✅ 2993ms
Request Payload.Flags Request Uses V2 Query Param ✅ 2984ms
Request Payload.Flags Request Hits Flags Path Not Decide ✅ 2977ms
Request Payload.Flags Request Omits Authorization Header ✅ 2899ms
Request Payload.Token In Flags Body Matches Init ✅ 2873ms
Request Payload.Groups Round Trip ✅ 2934ms
Request Payload.Groups Default To Empty Object ✅ 3027ms
Request Payload.Person Properties Distinct Id Auto Populated When Caller Omits It ✅ 2976ms
Request Payload.Disable Geoip False Propagates As Geoip Disable False ✅ 2913ms
Request Payload.Disable Geoip Omitted Defaults To False ✅ 3120ms
Request Payload.Flag Keys To Evaluate Contains Only Requested Key ✅ 3121ms
Request Lifecycle.No Flags Request On Init Alone ✅ 198ms
Request Lifecycle.No Flags Request On Normal Capture ✅ 3382ms
Request Lifecycle.Two Flag Calls Produce Two Remote Requests ✅ 5809ms
Request Lifecycle.Mock Response Value Is Returned To Caller ✅ 2909ms
Side Effect Events.Get Feature Flag Captures Feature Flag Called Event ✅ 3075ms

@marandaneto

Copy link
Copy Markdown
Member

should we fix this isntead of deprecating? that we only flush data in cellular if its cellular? feels like its a bug then

@turnipdabeets

turnipdabeets commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor Author

@marandaneto I thought about making .cellular actually work, since the SDK already detects cellular for $network_cellular. But that would change behavior for anyone already using it.

For context, .cellular has never done anything. posthog-ios v3 (#75, Nov 2023) added PostHogDataMode but only implemented .wifi, so .cellular has always behaved like .any. #117 (Oct 2024) mapped Dart's cellular straight to it, so it was a no-op on Flutter too. The doc comment saying "send data only on cellular" was never true.

If we implemented it now, anyone who set cellular would see events start pausing on WiFi, and on macOS always, because Reachability reports Ethernet as .wifi. No one has asked for cellular-only, and Android doesn't support dataMode at all. So I went with keeping today's behavior: map it to .any, deprecate it here, and remove it in the next major #890.

@dustinbyrne dustinbyrne left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review recommendation: approve. The existing enum case, raw values and default remain intact, and the queue handles .cellular and .any equivalently. The deprecation provides a clear migration without changing runtime behavior. No findings.

Static source review and existing CI only; no tests run locally. Human-driven, agent-assisted review.

@dustinbyrne dustinbyrne left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved following the completed source review.

Human-driven, agent-assisted review.

@turnipdabeets
turnipdabeets merged commit 2a92154 into main Oct 5, 2026
47 checks passed
@turnipdabeets
turnipdabeets deleted the chore/deprecate-datamode-cellular branch October 5, 2026 13:51
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.

3 participants