Skip to content

fix(ios): Re-land SentrySDK.internal migration, bump Cocoa SDK to 9.24.0 - #6541

Open
alwx wants to merge 1 commit into
mainfrom
alwx/fix/6507
Open

fix(ios): Re-land SentrySDK.internal migration, bump Cocoa SDK to 9.24.0#6541
alwx wants to merge 1 commit into
mainfrom
alwx/fix/6507

Conversation

@alwx

@alwx alwx commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

📢 Type of change

  • Bugfix
  • New feature
  • Enhancement
  • Refactoring

📜 Description

Re-lands #6380 (the PrivateSentrySDKOnlySentrySDK.internal migration), which shipped in 8.19.0 and was reverted in 8.20.0 by #6491, now that the underlying sentry-cocoa bug is fixed.

Three parts:

  1. Bump sentry-cocoa 9.19.1 → 9.24.0 (podspec + xcframework SHA256, via scripts/update-cocoa.sh set-version 9.24.0).
  2. Revert the revert of refactor(ios): Migrate from PrivateSentrySDKOnly to SentrySDK.internal #6380 — applied cleanly, no conflicts. The only commits touching packages/core/ios since the revert were the two release commits.
  3. New regression guardRNSentryCocoaTester/RNSentryCocoaTesterTests/RNSentryScreenshotSourceTests.swift.

Re-landing also restores the two improvements #6491 removed along with the migration: the fetchViewHierarchy nil-guard (returns null instead of a zero-byte attachment when capture fails) and the RNSentryTimeToDisplay extern linkage change.

Important

This re-introduces the RN < 0.75 requirement from 8.19.0: on React Native versions where React-hermes (or another RN pod) is not modularized by default (e.g. RN 0.71), users must add use_modular_headers! to their ios/Podfile. CocoaPods refuses to integrate a Swift pod against non-modular ObjC dependencies, and RNSentryInternal.swift makes RNSentry a Swift pod. Called out in the CHANGELOG.

💡 Motivation and Context

Fixes #6507.

#6380 broke all iOS screenshot capture — Feedback Widget screenshot, attachScreenshot, and Sentry.captureScreenshot() (#6497).

Root cause was in sentry-cocoa, not in RN: constructing SentryInternalApi eagerly reads SentryDependencyContainer.screenshotSource, which was a lazy var whose builder returns nil while startOptions is unset. Being lazy, that nil was cached for the process lifetime. RN reads SentrySDK.internal before SentrySDK.start — from RNSentryStart itself, and from JS integrations calling native methods like fetchNativeAppStart / fetchNativeSdkInfo during init — so the source was reliably poisoned. A targeted RN-side fix wasn't possible because JS controls the timing of those calls, hence the full revert.

getsentry/sentry-cocoa#8578 makes screenshotSource a computed property so getOptionalLazyVar re-runs the builder until startOptions is available, and only then caches. It shipped in 9.24.0.

I also confirmed:

  • SentrySDK.internal is a computed property that builds a fresh SentryInternalApi per access, so the eager read in SentryInternalScreenshotApi.init is harmless once screenshotSource rebuilds.
  • viewHierarchyProvider is still a lazy var, but its builder never touches startOptions, so it cannot be poisoned the same way.
  • No API drift in Sources/Swift/HybridSDK/ between 9.19.1 and 9.24.0 — the only diffs are @_implementationOnly importinternal import. Every symbol RNSentryInternal.swift bridges still exists with the same signature.
  • Nothing in the 9.20.0–9.24.0 cocoa changelog affects RN. enableReplayNetworkDetailsCapturing was removed in 9.22.0 but RN never set it.

💚 How did you test it?

New regression test (RNSentryScreenshotSourceTests): reads SentrySDK.internal before SentrySDK.start, then starts via RNSentryStart.start with attachScreenshot and asserts SentrySDK.internal.screenshot.capture() is non-nil. Verified it is not vacuous:

sentry-cocoa Result
9.19.1 (buggy) XCTAssertNotNil failed — reproduces #6497
9.24.0 (fixed) ✅ passes

Full native suiteRNSentryCocoaTester, Release config, iPhone simulator, Xcode 26.1: 163 tests, 0 failures.

Linters: swiftlint --strict clean (13 files, 0 violations), clang-format clean.

No JS/TS source changed, so no api-report or JS test impact.

📝 Checklist

  • I added tests to verify changes.
  • No new PII added or SDK only sends newly added PII if sendDefaultPII is enabled.
  • I updated the docs if needed.
  • I updated the wizard if needed.
  • All tests passing.
  • Public API changes reviewed by another Mobile SDK team member or implemented according to the develop docs spec.
  • No breaking changes.

🔮 Next steps

Needs the ready-to-merge label before merging so the native / E2E / sample-app workflows run — the iOS feedback E2E flow is what surfaced #6497 in the first place and should be confirmed green.

Two pre-existing problems found while writing the regression test, both unrelated to this change and left for follow-up issues:

  1. RNSentryStartTests.swift and RNSentryStartFromFileTests.swift are not in the Xcode test target. They were dropped from project.pbxproj around the v7 merge (6ab6b160) and have not compiled or run since. They no longer build (Options.enableTracing was removed in cocoa v9), and once that's fixed every test in them crashes — see below. I intentionally did not re-enable them here; that's why the new regression test lives in its own file.
  2. RNSentrySDK.start proceeds with options == nil when sentry.options.json is absent or unparseable (packages/core/ios/RNSentrySDK.m L64-72). The @{} fallback also fails validation ("Invalid DSN URL") and returns nil, but the code carries on into updateWithReactDefaults: / configureOptions(...) / startWithOptions:. Identical before and after refactor(ios): Migrate from PrivateSentrySDKOnly to SentrySDK.internal #6380 — both PrivateSentrySDKOnly.optionsWithDictionary:didFailWithError: and SentrySDK.internal.options(fromDictionary:) funnel into the same SentryOptionsInternal initWithDict:, which returns nil on failure. From ObjC it silently no-ops; from Swift (options.dsn = … on an implicitly-unwrapped SentryOptions!) it segfaults.

@github-actions

github-actions Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Semver Impact of This PR

None (no version bump detected)

📋 Changelog Preview

This is how your changes will appear in the changelog.
Entries from this PR are highlighted with a left border (blockquote style).


  • fix(ios): Re-land SentrySDK.internal migration, bump Cocoa SDK to 9.24.0 by alwx in #6541
  • chore(deps): bump brace-expansion from 1.1.16 to 1.1.18 by dependabot in #6552
  • fix(expo): resolve plugin config when registered as bare '@sentry/react-native' by antonis in #6543
  • fix(ios): make the RNSentry SPEC CHECKSUM in Podfile.lock machine-independent by alwx in #6534
  • chore(deps): update Android SDK to v8.51.0 by github-actions in #6539
  • chore(deps): update Sentry Android Gradle Plugin to v6.17.0 by github-actions in #6544
  • feat(core): Extend TurboModule instrumentation to legacy NativeModules by alwx in #6504
  • feat(ios): Introduce enableMetricKit option by alwx in #6540

🤖 This preview updates automatically when you update the PR.

@github-actions

github-actions Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor
Fails
🚫 Pull request is not ready for merge, please add the "ready-to-merge" label to the pull request

Generated by 🚫 dangerJS against 3d54bc6

Comment thread packages/core/ios/RNSentry+fetchNativeStack.m
Reapplies #6380 (reverted in 8.20.0 by #6491) now that the underlying
sentry-cocoa bug is fixed.

#6380 migrated the iOS code off the deprecated PrivateSentrySDKOnly SPI onto
the SentrySDK.internal Swift API. It shipped in 8.19.0 and broke every iOS
screenshot (Feedback Widget screenshot, attachScreenshot,
Sentry.captureScreenshot) — #6497.

Root cause was in sentry-cocoa: constructing SentryInternalApi eagerly reads
SentryDependencyContainer.screenshotSource, a lazy var whose builder returns
nil while startOptions is unset. Being lazy, that nil was cached for the
process lifetime, and RN reads SentrySDK.internal before SentrySDK.start
(from RNSentryStart, and from JS integrations calling fetchNativeAppStart /
fetchNativeSdkInfo during init). getsentry/sentry-cocoa#8578 makes
screenshotSource a computed property so the builder re-runs until
startOptions is available; it shipped in 9.24.0, which this bumps to.

Adds RNSentryScreenshotSourceTests as a regression guard: it reads
SentrySDK.internal before starting the SDK and asserts screenshot capture
still works. Verified to fail against 9.19.1 and pass against 9.24.0.

RNSentry+fetchNativeStack.m was the last production file still reading
options through the hand-rolled SentrySDKInternal redeclaration in
RNSentry.h. It now goes through SentrySDKWrapper.debug like the rest of
RNSentry.mm, and the redeclaration is gone.

Re-landing also restores the two improvements the revert removed: the
fetchViewHierarchy nil-guard (returns null instead of a zero-byte
attachment on capture failure) and the RNSentryTimeToDisplay extern linkage.

Fixes #6507.
@alwx
alwx marked this pull request as ready for review August 3, 2026 08:39
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.

Reapply iOS SentrySDK.internal migration (#6380) after sentry-cocoa fixes screenshotSource lazy-var poisoning

1 participant