Skip to content

chore!: remove PostHogSessionReplayConfig.screenshotMode - #973

Merged
turnipdabeets merged 1 commit into
chore/v4-remove-deprecatedfrom
chore/v4-remove-screenshot-mode
Oct 27, 2026
Merged

turnipdabeets merged 1 commit into
chore/v4-remove-deprecatedfrom
chore/v4-remove-screenshot-mode

Conversation

@turnipdabeets

Copy link
Copy Markdown
Contributor

💡 Motivation and Context

Addresses ioannisj's review on #873 (#873): delete PostHogSessionReplayConfig.screenshotMode outright instead of keeping it as a deprecated no-op.

With wireframe capture gone, the property always read true and dropped writes. An app that set it to false to keep pixels out of recordings would still compile on 4.0, get only a deprecation warning, and start uploading masked screenshots of custom-drawn views, maps and video. Removing it makes the compiler flag the assignment so those apps have to choose: mask what's sensitive (postHogMask(), ph-no-capture, maskAllImages/maskAllTextInputs) or turn replay off with sessionReplay = false.

Changes:

  • Remove the property (Swift and its @objc exposure). No internal code read it.
  • Drop the one test assignment in PostHogMaskFlattenedContentTest. No test covered only this property, and no example app set it.
  • Remove it from api/posthog-ios.public-api.txt.
  • In .changeset/v4-major-release.md, replace the "deprecated and has no effect" sub-bullet with a Breaking: removal entry under Removed.

No @available(*, unavailable) stub. I went with plain deletion, the same way screenshotModeBackgroundCapture (#937), debouncerDelay and maskPhotoLibraryImages were removed:

  • A stub would stay in the public API snapshot and need a getter/setter body.
  • With @objc, it would still be settable at runtime through KVC and visible to Objective-C. Without @objc, Objective-C callers get the plain "property not found" error anyway.
  • "Value of type 'PostHogSessionReplayConfig' has no member 'screenshotMode'" already points at the line to delete, and the changeset entry says what to use instead.

Wrapper SDKs: posthog-flutter and the React Native plugin set screenshotMode on the iOS config. Once they move to 4.0 they must stop setting it, or they won't compile. PostHog/posthog-js#5236 already does this for React Native. This PR doesn't change either wrapper.

💚 How did you test it?

Run locally on Xcode 26.4.1:

Check Result
make lint Passed (0 serious violations)
make buildSdk (iOS, macOS, Mac Catalyst, tvOS, watchOS, visionOS) Passed
iOS simulator: PostHogMaskFlattenedContentTest (the only test that set the property), which builds the full iOS test target Passed: 10 tests; the 1 known issue is an existing withKnownIssue
make test (macOS swift test) 1153 tests; 6 failed in storage, push-notification, logs-queue, identity and feature-flag suites
make testOniOSSimulator (full iOS suite) Not run: the script picked an iPhone 17 Pro simulator that this Xcode can't target

About the make test failures: the code this PR touches is inside #if os(iOS), so the macOS test build doesn't include it, and none of the failing suites involve replay. I didn't run the same tests on the base branch to compare. Most of the failures (13 of the 21 issues) are in PostHogStorageTest app-group/backup tests, which hit local sandbox and file-system limits.

Also checked that nothing else in the repo (SDK, tests, example apps, Objective-C samples) references screenshotMode. The only remaining mentions are historical CHANGELOG.md entries and the parent wireframe bullet in the changeset.

📝 Checklist

  • All commits are signed (see Commit signing)
  • 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 (edited the existing .changeset/v4-major-release.md instead of adding a new one)

🤖 Agent context

Autonomy: Human-driven (agent-assisted)

  • Written with Claude Code (Opus 5.5) as one of several follow-up PRs to the 4.0 integration branch, directed by a maintainer.
  • Matched the screenshotModeBackgroundCapture removal in chore!: remove experimental screenshotModeBackgroundCapture #937. I considered an unavailable stub and decided against it (reasons above).
  • The public API snapshot was regenerated with scripts/check-public-api.sh --update on Xcode 26.4.1. That run also rewrote several unrelated closure types to @Sendable (BeforeSendBlock, reloadFeatureFlags(_:) and others), which comes from the local toolchain. I kept only the screenshotMode line removal so this PR stays focused.

🤖 Generated with Claude Code

Session replay always records masked screenshots, so the deprecated property only read true and dropped writes. An app that set it to false to keep pixels out of recordings would compile against 4.0 with just a warning. Deleting it makes the compiler flag the assignment, matching the screenshotModeBackgroundCapture removal.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@turnipdabeets turnipdabeets self-assigned this Oct 27, 2026
@turnipdabeets turnipdabeets mentioned this pull request Oct 27, 2026
10 of 19 tasks
@github-actions

Copy link
Copy Markdown
Contributor

posthog-ios Compliance Report

Date: 2026-10-27T16:48:21.032557+00:00
Duration: 214190ms

⚠️ Some Tests Failed

46/47 tests passed, 1 failed


Capture Tests

⚠️ 29/30 tests passed, 1 failed

View Details
Test Status Duration
Format Validation.Event Has Required Fields ✅ 2839ms
Format Validation.Event Has Uuid ✅ 2748ms
Format Validation.Event Has Lib Properties ✅ 2737ms
Format Validation.Distinct Id Is String ✅ 2673ms
Format Validation.Token Is Present ✅ 2720ms
Format Validation.Custom Properties Preserved ✅ 2781ms
Format Validation.Event Has Timestamp ✅ 2746ms
Format Validation.Non Utc Event Timestamp Is Converted To Utc ✅ 2710ms
Retry Behavior.Retries On 503 ✅ 11201ms
Retry Behavior.Does Not Retry On 400 ✅ 4802ms
Retry Behavior.Does Not Retry On 401 ✅ 2262ms
Retry Behavior.Respects Retry After Header ✅ 7768ms
Retry Behavior.Implements Backoff ✅ 15295ms
Retry Behavior.Retries On 500 ✅ 5313ms
Retry Behavior.Retries On 502 ✅ 9271ms
Retry Behavior.Retries On 504 ✅ 8843ms
Retry Behavior.Max Retries Respected ❌ 15408ms
Deduplication.Generates Unique Uuids ✅ 2770ms
Deduplication.Preserves Uuid On Retry ✅ 9202ms
Deduplication.Preserves Uuid And Timestamp On Retry ✅ 10290ms
Deduplication.Preserves Uuid And Timestamp On Batch Retry ✅ 7743ms
Deduplication.No Duplicate Events In Batch ✅ 2793ms
Deduplication.Different Events Have Different Uuids ✅ 3163ms
Compression.Sends Gzip When Enabled ✅ 2845ms
Batch Format.Uses Proper Batch Structure ✅ 2779ms
Batch Format.Flush With No Events Sends Nothing ✅ 344ms
Batch Format.Multiple Events Batched Together ✅ 2880ms
Error Handling.Does Not Retry On 403 ✅ 4689ms
Error Handling.Does Not Retry On 413 ✅ 4900ms
Error Handling.Retries On 408 ✅ 9306ms

Failures

retry_behavior.max_retries_respected

Expected 4 requests, got 5

Feature_Flags Tests

✅ 17/17 tests passed

View Details
Test Status Duration
Request Payload.Request With Person Properties Device Id ✅ 2752ms
Request Payload.Flags Request Uses V2 Query Param ✅ 2666ms
Request Payload.Flags Request Hits Flags Path Not Decide ✅ 2816ms
Request Payload.Flags Request Omits Authorization Header ✅ 2771ms
Request Payload.Token In Flags Body Matches Init ✅ 2752ms
Request Payload.Groups Round Trip ✅ 2767ms
Request Payload.Groups Default To Empty Object ✅ 2808ms
Request Payload.Disable Geoip False Propagates As Geoip Disable False ✅ 2811ms
Request Payload.Disable Geoip Omitted Defaults To False ✅ 2680ms
Request Payload.Flag Keys To Evaluate Contains Only Requested Key ✅ 2681ms
Request Lifecycle.No Flags Request On Init Alone ✅ 61ms
Request Lifecycle.No Flags Request On Normal Capture ✅ 2725ms
Request Lifecycle.Two Flag Calls Produce Two Remote Requests ✅ 5463ms
Request Lifecycle.Mock Response Value Is Returned To Caller ✅ 2735ms
Retry Behavior.Retries Flags On 502 ✅ 2777ms
Retry Behavior.Retries Flags On 504 ✅ 2765ms
Side Effect Events.Get Feature Flag Captures Feature Flag Called Event ✅ 2878ms

@turnipdabeets
turnipdabeets marked this pull request as ready for review October 27, 2026 17:20
@turnipdabeets
turnipdabeets requested a review from a team as a code owner October 27, 2026 17:20
@turnipdabeets turnipdabeets mentioned this pull request Oct 27, 2026
4 of 6 tasks

@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.

Reviewed ae4b6a7. This removes an ineffective option without changing replay behavior; the public API snapshot and v4 migration guidance are consistent. No issues found.

AI-assisted review.

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.

2 participants