Skip to content

[RUM-18631] Consume dd-sdk-ios through Swift Package Manager - #1455

Open
saraSr5 wants to merge 9 commits into
developfrom
sara/RUM-18631/spm-migration
Open

saraSr5 wants to merge 9 commits into
developfrom
sara/RUM-18631/spm-migration

Conversation

@saraSr5

@saraSr5 saraSr5 commented Sep 29, 2026 •

Copy link
Copy Markdown

What does this PR do?

Builds on @sbarrio's sbarrio/test/spm-dependency-support spike and validates it end to end.

The native iOS SDK is now resolved through Swift Package Manager via React Native's spm_dependency helper, replacing the seven dd-sdk-ios pods. All three sample apps build and run with no Datadog* CocoaPods installed: example (old arch, SDK confirmed live in console), example-new-architecture (Fabric, RN 0.76.9) and benchmarks.

Three fixes on top of the spike:

React-RCTText missing from the session replay podspec. RCTTextExtractor.mm references the RCTText classes directly, but the dependency was only declared on the test spec. Static linking deferred the undefined symbols to the app link and hid it; dynamic linking, which SPM resolution requires, exposes it. Pre-existing bug, surfaced not caused by this change.

Duplicate OpenTelemetryApi module in benchmarks. DatadogTrace resolves opentelemetry-swift-core through SwiftPM while the Podfile pulled OpenTelemetry-Swift-Sdk from CocoaPods, so two copies entered the build and the module scanner warned across every target touching it. Both products now come from the same SwiftPM package.

Native test suites restored. The spike dropped the test_spec blocks, orphaning 18 test files and breaking the three CI jobs that run xcodebuild … test. The stated blockers did not hold: no test uses anything DD_SDK_COMPILED_FOR_TESTING guards (and its injection was broken anyway — targets.detect returns one target, not six), and @testable resolves against SwiftPM modules unchanged. The only real breakage was 16 files using Date/URL/URLRequest without importing Foundation, which used to arrive transitively through the CocoaPods modules. Session replay and webview also link DatadogInternal explicitly, since their tests reference its protocol descriptors and it is not one of the SPM products those pods request. Now at 184 tests in core on both architectures, plus session replay and webview.

Motivation

RUM-18631. The CocoaPods & Carthage deprecation RFC gates stopping publication of dd-sdk-ios to Trunk on React Native having an SPM path, as the last consumer without one. This shows it exists today, with no changes required in dd-sdk-ios.

Only the native SDK changes. React Native and our wrapper pods still install through CocoaPods, resolved from node_modules via autolinking — a path Trunk going read-only does not affect.

Additional Notes

Two calls for a reviewer:

  • No dual path for RN < 0.75. The podspecs raise instead of falling back to s.dependency, but all four packages still declare react-native: ">=0.63.4 <1.0", so a user on RN 0.72 installs cleanly from npm and only fails at pod install. If the raise stays, that range should become >=0.75.0 <1.0 — a breaking change
  • ~25 lines of SPM scaffolding duplicated across the four podspecs. No shared .rb: each package publishes only its own directory to npm, so require_relative across packages breaks once installed. The require.resolve pattern would work, but two satellite packages do not declare @datadog/mobile-react-native in package.json.

Requires dynamic linking, which the sample Podfiles now set unconditionally. DatadogInternal is still reached through an explicit FRAMEWORK_SEARCH_PATHS entry into PackageFrameworks/; a proper @_spi(Internal) surface is separate, larger work.

Review checklist

  • Feature or bugfix MUST have appropriate tests
  • Make sure you discussed the feature or bugfix with the maintaining team in an Issue
  • Make sure each commit and the PR mention the Issue number (cf the CONTRIBUTING doc)
  • If this PR is auto-generated, please make sure also to manually update the code related to the change

@datadog-prod-us1-3

datadog-prod-us1-3 Bot commented Sep 29, 2026 •

Copy link
Copy Markdown

Tests

✅ All CI checks and tests passed.

🎉 All green!

🧪 All tests passed
❄️ No new flaky tests detected

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: 08b6ad4 | Docs | View more details | Give us feedback!

@saraSr5

saraSr5 commented Sep 29, 2026

Copy link
Copy Markdown
Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

To use Codex here, create a Codex account and connect to github.

@saraSr5
saraSr5 marked this pull request as ready for review September 29, 2026 14:55
@saraSr5
saraSr5 requested a review from a team as a code owner September 29, 2026 14:55
Copilot AI balanced review requested due to automatic review settings September 29, 2026 14:55

Copilot AI 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.

Copilot review overview

🟡 Changes recommended

Session Replay asset lookup breaks under dynamic linkage, and the advertised React Native support range and internal native test target remain unresolved.

Review effort: Balanced
Findings: 1 High severity · 2 Medium severity · 1 Low severity

Open (4)
What changed in this PR

This PR moves the React Native wrapper’s native iOS SDK dependencies from CocoaPods to Swift Package Manager, supporting the planned end of CocoaPods publication for dd-sdk-ios.

Changes:

  • Replace native SDK pod dependencies with Swift Package Manager products and update the three sample apps for dynamic framework linkage.
  • Restore native test targets and add imports and link settings needed by the new dependency layout.
  • Adjust Session Replay resources, WebView headers, and benchmark OpenTelemetry dependencies.
File Description
packages/​react-native-webview/​ios/​Sources/​RCTDatadogWebViewManager.h Supports framework header imports.
packages/​react-native-webview/​ios/​Sources/​RCTDatadogWebView.h Supports framework header imports.
packages/​react-native-webview/​ios/​Sources/​DatadogSDKReactNativeWebView.h Supports framework header imports.
packages/​react-native-webview/​DatadogSDKReactNativeWebView.podspec Requests the native Swift package product.
packages/​react-native-session-replay/​ios/​Tests/​RCTTextViewRecorderTests.swift Imports Foundation explicitly.
packages/​react-native-session-replay/​ios/​Tests/​DdSessionReplayTests.swift Imports Foundation explicitly.
packages/​react-native-session-replay/​ios/​Sources/​Utils/​Bundle+SessionReplay.swift Adapts asset-bundle lookup.
packages/​react-native-session-replay/​DatadogSDKReactNativeSessionReplay.podspec Updates resources and Swift package linkage.
packages/​internal-testing-tools/​DatadogInternalTesting.podspec Requests DatadogCore through SwiftPM.
packages/​core/​ios/​Tests/​RUMMocks.swift Imports Foundation explicitly.
packages/​core/​ios/​Tests/​RNDdSdkConfigurationTests.swift Imports Foundation explicitly.
packages/​core/​ios/​Tests/​ModulesTest.swift Imports Foundation explicitly.
packages/​core/​ios/​Tests/​MockRUMMonitor.swift Imports Foundation explicitly.
packages/​core/​ios/​Tests/​MockDatadogCore.swift Imports Foundation explicitly.
packages/​core/​ios/​Tests/​GlobalStateTests.swift Imports Foundation explicitly.
packages/​core/​ios/​Tests/​DdTraceTests.swift Imports Foundation explicitly.
packages/​core/​ios/​Tests/​DdSdkTests.swift Imports Foundation explicitly.
packages/​core/​ios/​Tests/​DdSdkSessionStartedListenerTests.swift Imports Foundation explicitly.
packages/​core/​ios/​Tests/​DdSdkNativeInitializationTests.swift Imports Foundation explicitly.
packages/​core/​ios/​Tests/​DdRumTests.swift Imports Foundation explicitly.
packages/​core/​ios/​Tests/​DdLogsTests.swift Imports Foundation explicitly.
packages/​core/​ios/​Tests/​DdFlagsTests.swift Imports Foundation explicitly.
packages/​core/​ios/​Tests/​DatadogSdkWrapperTests.swift Imports Foundation explicitly.
packages/​core/​ios/​Tests/​AnyEncodableTests.swift Imports Foundation explicitly.
packages/​core/​DatadogSDKReactNative.podspec Replaces native pods with SwiftPM products.
example/​ios/​Podfile.lock Records the revised pod graph.
example/​ios/​Podfile Enables dynamic frameworks.
example/​ios/​ddSdkReactnativeExample/​PrivacyInfo.xcprivacy Reorders existing privacy entries.
example/​ios/​DdSdkReactNativeExample.xcworkspace/​xcshareddata/​swiftpm/​Package.resolved Pins Swift packages.
example/​ios/​DdSdkReactNativeExample.xcodeproj/​project.pbxproj Updates framework linkage and header paths.
example-new-architecture/​ios/​Podfile.lock Records the revised pod graph.
example-new-architecture/​ios/​Podfile Enables dynamic frameworks.
example-new-architecture/​ios/​DdSdkReactNativeExample/​PrivacyInfo.xcprivacy Reorders existing privacy entries.
example-new-architecture/​ios/​DdSdkReactNativeExample.xcworkspace/​xcshareddata/​swiftpm/​Package.resolved Pins Swift packages.
example-new-architecture/​ios/​DdSdkReactNativeExample.xcodeproj/​project.pbxproj Updates framework linkage and header paths.
benchmarks/​ios/​Podfile.lock Removes native SDK and OpenTelemetry pods.
benchmarks/​ios/​Podfile Enables dynamic frameworks and removes the OpenTelemetry pod.
benchmarks/​ios/​BenchmarkRunner/​PrivacyInfo.xcprivacy Reorders existing privacy entries.
benchmarks/​ios/​BenchmarkRunner.xcworkspace/​xcshareddata/​swiftpm/​Package.resolved Pins Swift packages.
benchmarks/​ios/​BenchmarkRunner.xcodeproj/​project.pbxproj Links OpenTelemetry Swift package products.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread packages/core/DatadogSDKReactNative.podspec
Comment thread packages/internal-testing-tools/DatadogInternalTesting.podspec Outdated
Comment on lines +12 to +14
# The native iOS SDK is resolved through Swift Package Manager, using React Native's
# `spm_dependency` podspec helper. This requires React Native >= 0.75 and an app that links
# pods as dynamic frameworks (`use_frameworks! :linkage => :dynamic`).

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

This also looks correct, I'll work on it

@saraSr5
saraSr5 marked this pull request as draft September 29, 2026 15:08
@saraSr5
saraSr5 marked this pull request as ready for review September 29, 2026 15:14
@sbarrio
sbarrio self-requested a review September 30, 2026 07:10
…ls test spec

The webview podspec only requested DatadogWebViewTracking via spm_dependency, relying on
FRAMEWORK_SEARCH_PATHS to make DatadogInternal importable. That's enough to compile against it,
but not to link it: unlike DatadogCore and DatadogSessionReplay, DatadogWebViewTracking's own
autolink metadata doesn't pull DatadogInternal onto this target's link line, so
RCTDatadogWebViewTracking.swift's direct references to it were left unresolved at link time.
Verified with a full DerivedData wipe + clean build, not just a retry.

Also documents the missing use_frameworks! :linkage => :dynamic requirement in the core,
session-replay, and webview READMEs, and restores internal-testing-tools' test spec following
the same pattern as the other three packages -- though unlike those, it could not be verified
against a real build: no app in this repo installs this pod, and a local CocoaPods/Xcode
compatibility issue corrupts Pods.xcodeproj when adding it as a fourth SPM-consuming target.
Copilot AI balanced review requested due to automatic review settings September 30, 2026 07:38
@saraSr5
saraSr5 requested a review from a team as a code owner September 30, 2026 07:38

Copilot AI 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.

Copilot review overview

🔵 Needs a closer look

The cross-package linkage migration has an unresolved benchmark target dependency issue, and its tvOS path remains unverified.

Review effort: Balanced
Findings: 1 Low severity

Open (1)
Resolved since last review (3)
Previously missed (1)

In code that hasn't changed since last review

Medium severity Declare OpenTelemetry products as BenchmarkRunner dependencies

benchmarks/​ios/​BenchmarkRunner.xcodeproj/​project.pbxproj:21

The two OpenTelemetry products have framework-phase entries and a project-level package reference, but the BenchmarkRunner target has no packageProductDependencies list (its target definition is at lines 164–184). Xcode needs the product IDs on the target to establish its package build dependencies; otherwise clean builds may fail to resolve or link the Swift imports. Add 10520E8B306BAEDB00BBFBFF (OpenTelemetryApi) and 10520E8D306BAEDB00BBFBFF (OpenTelemetrySdk) to BenchmarkRunner's packageProductDependencies, while retaining their framework-phase entries.

…cies

The Frameworks build phase and the project's packageReferences already referenced
OpenTelemetryApi/OpenTelemetrySdk, but the BenchmarkRunner PBXNativeTarget itself never listed
them in packageProductDependencies -- the field Xcode actually uses to resolve and order the
package build. Verified with a full DerivedData wipe.
Copilot AI balanced review requested due to automatic review settings September 30, 2026 08:31

Copilot AI 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.

Copilot review overview

🔵 Needs a closer look

The cross-package linking migration leaves tvOS unverified, and the restored internal-testing subspec is not run by an iOS test host.

Review effort: Balanced
Findings: 1 Low severity

Open (1)
Previously missed (2)

In code that hasn't changed since last review

Medium severity Update tvOS dependency compatibility test and verify framework resolution

packages/​core/​DatadogSDKReactNative.podspec:39

The core pod still supports tvOS, but this change requests DatadogWebViewTracking on tvOS too. ios/Tests/TvOSCompatibilityTests.swift:10-15 still says that product is unavailable there and cites the removed s.ios.dependency; its source-guard checks do not exercise SwiftPM resolution or linking. Please update the test's stated contract and verify a tvOS install/build (or keep the dependency platform-specific) before relying on that test for tvOS compatibility.

Medium severity Run restored internal testing subspec regression tests in CI

packages/​internal-testing-tools/​DatadogInternalTesting.podspec:45

Restoring this Tests subspec does not yet run its logging regression test. Neither example Podfile selects DatadogInternalTesting/Tests, the generated sample lockfiles omit the pod, and the iOS CI test jobs only run the core and Session Replay schemes. Add the subspec to an iOS test host and run its test scheme in CI so DdInternalTestingTests.swift is compiled and executed.

Copilot AI balanced review requested due to automatic review settings September 30, 2026 09:25

Copilot AI 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.

Copilot review overview

🔵 Needs a closer look

The migration relies on internal SwiftPM framework paths, and end-to-end tvOS linkage remains unverified.

Review effort: Balanced
Findings: 1 Low severity

Open (1)

@saraSr5

saraSr5 commented Sep 30, 2026

Copy link
Copy Markdown
Author

Copilot review overview

🔵 Needs a closer look

The migration relies on internal SwiftPM framework paths, and end-to-end tvOS linkage remains unverified.

Review effort: Balanced Findings: 1 Low severity

Open (1)

Quick update on this and the tvOS thread from before:

Linkage docs: added. The core, session-replay, and webview READMEs now mention use_frameworks! :linkage => :dynamic. This thread is anchored to the podspec line, so it's probably still showing open even though the docs are there.

tvOS: fixed the stale comment. I also tried checking if DatadogWebViewTracking itself still builds for tvOS and it does. What I couldn't check is whether our pod builds for tvOS end to end, as far as I can tell, mainline React Native 0.76.9 doesn't declare tvOS support at all here, so I'm not sure it's even possible without switching to react-native-tvos.

@sbarrio do you know if there's a way to test this that I'm missing? Happy to run it if so.

Copilot AI balanced review requested due to automatic review settings October 2, 2026 12:28

Copilot AI 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.

Copilot review overview

🟡 Changes recommended

Release automation still uses the old dependency patterns and cannot extract or update the new iOS SDK version assignments.

Review effort: Balanced
Findings: 1 High severity · 1 Low severity

Open (2)

# - DatadogSDKReactNativeSessionReplay.podspec
# - DatadogSDKReactNativeWebView.podspec
# - DatadogInternalTesting.podspec
datadog_ios_version = '3.16.0'
Copilot AI balanced review requested due to automatic review settings October 2, 2026 12:50

Copilot AI 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.

Copilot review overview

🔵 Needs a closer look

Internal-framework linking workarounds and missing end-to-end tvOS validation warrant final native-platform review.

Review effort: Balanced
Findings: 1 High severity · 1 Low severity

Open (2)

Copilot AI 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.

Copilot review overview

🔵 Needs a closer look

The native-linking migration has unresolved build-setting issues and lacks end-to-end tvOS validation.

Review effort: Balanced
Findings: 3 High severity · 1 Low severity

Open (4)

Comment thread packages/core/DatadogSDKReactNative.podspec Outdated
Comment thread packages/internal-testing-tools/DatadogInternalTesting.podspec Outdated
Copilot AI balanced review requested due to automatic review settings October 2, 2026 13:31

Copilot AI 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.

Copilot review overview

🔵 Needs a closer look

The native linkage migration relies on internal-framework build paths, and end-to-end tvOS compatibility still requires human validation.

Review effort: Balanced
Findings: 1 High severity · 1 Low severity

Open (2)
Resolved since last review (2)

@saraSr5

saraSr5 commented Oct 2, 2026

Copy link
Copy Markdown
Author

Copilot review overview

🔵 Needs a closer look

The native linkage migration relies on internal-framework build paths, and end-to-end tvOS compatibility still requires human validation.

Review effort: Balanced Findings: 1 High severity · 1 Low severity

Open (2)

Resolved since last review (2)

@copilot-pull-request-reviewer

High: release scripts:
Fixed in 09d011e: both scripts now read datadog_ios_version and include DatadogInternalTesting.podspec. Verified by running them against all four podspecs.

Low: dynamic framework linkage:
Already documented: use_frameworks! :linkage => :dynamic is in the Setup section of the core, session-replay and webview READMEs (added in fd15fea).

This branch has not been deployed

No deployments
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.

4 participants