Conversation
PR SummaryLow Risk Overview Includes Reviewed by Cursor Bugbot for commit 3cd997b. Bugbot is set up for automated code reviews on this repo. Configure here. |
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
The source-list regression test does not detect nested Objective-C or Objective-C++ files included by the podspec.
Review effort: Balanced
Findings: 1
What changed in this PR
Adds experimental Swift Package Manager support for React Native 0.87+ while preserving CocoaPods behavior.
Changes:
- Adds a two-target Swift package manifest with mParticle/Rokt dependencies.
- Publishes the manifest and documents experimental setup.
- Adds source-list synchronization coverage.
| File | Description |
|---|---|
Package.swift |
Defines Swift and Objective-C++ targets and dependencies. |
package.json |
Includes the manifest in npm releases. |
README.md |
Documents experimental SPM setup. |
js/__tests__/package-swift-sources.test.ts |
Checks the hand-maintained source list. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| const listed = new Set( | ||
| [...manifest.matchAll(/"(ios\/RNMParticle\/[^"/]+\.(?:h|m|mm))"/g)].map( | ||
| match => match[1] | ||
| ) | ||
| ); | ||
| const onDisk = fs | ||
| .readdirSync(path.join(root, 'ios', 'RNMParticle')) | ||
| .filter(file => /\.(h|m|mm)$/.test(file)) | ||
| .map(file => `ios/RNMParticle/${file}`); |
There was a problem hiding this comment.
Fixed in 3cd997b. The test now walks ios/RNMParticle recursively (readdirSync with recursive: true), and the manifest regex accepts nested paths. Adding a nested .m file now fails the test.
React Native 0.87's Swift Package Manager mode stops with "Package.swift is missing" for this library, and `spm scaffold` drops its native dependencies. This hand-written manifest has two targets, since SwiftPM cannot mix languages in one: the Swift layer, and the Objective-C++ module with RCT_NEW_ARCH_ENABLED defined. The mParticle and RoktContracts version ranges match the podspec, and the package URLs match the kits'. The manifest is shipped in the npm package. A jest test keeps its source list in step with ios/RNMParticle, because CI does not build it. The README describes the mode as experimental and not for production. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
f63aa19 to
3cd997b
Compare

Why
React Native 0.87 added an experimental mode where an app uses Swift Package Manager instead of CocoaPods for everything, including React Native itself. Today that mode stops with "Package.swift is missing" as soon as an app adds this package, and React Native's generator cannot produce a working manifest for it. Once this lands, an app trying React Native's new mode can add this package and the mParticle SDK and get a working build, with one copy of each SDK. The mode is experimental in React Native itself and is documented as not for production; CocoaPods apps are unaffected.
Programme
Part of the plan to support Swift Package Manager in this package before the CocoaPods central repository becomes read-only on 2026-12-02 (CocoaPods announcement). This is the sixth of eight pull requests, all merging into the
workstation/spm-migrationbranch, which merges intomainonce the series is complete, and shipping together in one release; the plan record is internal and cannot be linked here.What changes
Before:
npx react-native spm addfails for this package, andnpx react-native spm scaffoldgenerates a manifest without the mParticle and Rokt dependencies.After: the package ships a hand-written
Package.swiftwith two targets, because Swift Package Manager cannot mix Swift and Objective-C++ in one target:RNMParticleSwift: the Swift layer from the previous pull request;ReactNativeMparticle: the Objective-C++ module, with the New Architecture define that React Native's code paths need.The mParticle and RoktContracts version ranges match the podspec. The package URLs match the ones the mParticle kits use, so Swift Package Manager treats them as one package.
package.jsonadds the manifest to the published files. A jest test fails if a source file anywhere underios/RNMParticleis missing from the manifest's list, because CI does not build this mode. The README gains an "Experimental: React Native Swift Package Manager mode" section with a not-for-production note.Start reading at
Package.swift. Left alone on purpose:react-native.config.jsname override: React Native derivesReactNativeMparticlefrom the npm name, and that config file would also affect CocoaPods autolinking;Linked work
Depends on: the Swift layer (branch
thomson-t/spm-05-swift-rokt-bridge) and the pull requests below it in this series; merge those first.Unblocks: the last pull request in this series, which removes the map form of embedded placeholders (branch
thomson-t/spm-07-remove-placeholder-map, stacked on this one).Related: React Native's proposal for Swift Package Manager and CocoaPods deprecation (react-native-community/discussions-and-proposals#994).
Rollout
Path: this merges into
workstation/spm-migration, notmain, so nothing reachesmainor a release until the whole series has merged there and that branch is merged intomain. It then ships in the next release. It only takes effect for apps that use React Native's Swift Package Manager mode.Feature flags: none; React Native's own
spm addis the opt-in.Turning it off: an app returns to CocoaPods. For the package, reverting this pull request and releasing again removes the manifest in the next version.
What we watch: this repository's issues, for build errors in React Native's Swift Package Manager mode and for any change in CocoaPods apps after upgrading.
Risks
Podfile.lockwas unchanged; we would see changed pods or duplicate classes after upgrading.Risk class: low.
Who
Written by: an automated coding agent (Claude Code), at an engineer's request, following the internal Swift Package Manager migration plan and its proof of concept.
Code reviewed before opening: an independent review agent reviewed the change before it was committed; its advisory about the hand-written source list led to the jest test.
Design reviewed before opening: the requesting engineer approved the migration plan, which specifies a hand-written two-target manifest.
Decision this implements: the requesting engineer's approval of the migration plan on 2026-09-28; the record is internal and cannot be linked.
Checked: on 2026-09-29, with Xcode 27.0 on an iOS 26.5 simulator:
npx react-native spm add --deintegrate --yesfound the package.Podfile.lockwas unchanged.Not checked: React Native 0.88, which is still a release candidate; Expo's Swift Package Manager autolinking preview (Expo 58), since the test app is on Expo 57; physical devices.
Size
Hand-written: 110 lines added and 1 removed in 4 files (24 of them the test).
Generated: none.
🤖 Generated with Claude Code