You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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
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.
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.
…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.
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.
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.
Run restored internal testing subspec regression tests in CI
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.
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.
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
Builds on @sbarrio's
sbarrio/test/spm-dependency-supportspike and validates it end to end.The native iOS SDK is now resolved through Swift Package Manager via React Native's
spm_dependencyhelper, replacing the sevendd-sdk-iospods. All three sample apps build and run with noDatadog*CocoaPods installed:example(old arch, SDK confirmed live in console),example-new-architecture(Fabric, RN 0.76.9) andbenchmarks.Three fixes on top of the spike:
React-RCTTextmissing from the session replay podspec.RCTTextExtractor.mmreferences theRCTTextclasses 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
OpenTelemetryApimodule inbenchmarks.DatadogTraceresolvesopentelemetry-swift-corethrough SwiftPM while the Podfile pulledOpenTelemetry-Swift-Sdkfrom 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_specblocks, orphaning 18 test files and breaking the three CI jobs that runxcodebuild … test. The stated blockers did not hold: no test uses anythingDD_SDK_COMPILED_FOR_TESTINGguards (and its injection was broken anyway —targets.detectreturns one target, not six), and@testableresolves against SwiftPM modules unchanged. The only real breakage was 16 files usingDate/URL/URLRequestwithout importing Foundation, which used to arrive transitively through the CocoaPods modules. Session replay and webview also linkDatadogInternalexplicitly, since their tests reference its protocol descriptors and it is not one of the SPM products those pods request. Now at 184 tests incoreon both architectures, plus session replay and webview.Motivation
RUM-18631. The CocoaPods & Carthage deprecation RFC gates stopping publication of
dd-sdk-iosto Trunk on React Native having an SPM path, as the last consumer without one. This shows it exists today, with no changes required indd-sdk-ios.Only the native SDK changes. React Native and our wrapper pods still install through CocoaPods, resolved from
node_modulesvia autolinking — a path Trunk going read-only does not affect.Additional Notes
Two calls for a reviewer:
raiseinstead of falling back tos.dependency, but all four packages still declarereact-native: ">=0.63.4 <1.0", so a user on RN 0.72 installs cleanly from npm and only fails atpod install. If theraisestays, that range should become>=0.75.0 <1.0— a breaking change.rb: each package publishes only its own directory to npm, sorequire_relativeacross packages breaks once installed. Therequire.resolvepattern would work, but two satellite packages do not declare@datadog/mobile-react-nativeinpackage.json.Requires dynamic linking, which the sample Podfiles now set unconditionally.
DatadogInternalis still reached through an explicitFRAMEWORK_SEARCH_PATHSentry intoPackageFrameworks/; a proper@_spi(Internal)surface is separate, larger work.Review checklist