Skip to content

feat: add Swift Package Manager support to sovran and core - #1347

Open
chrfalch wants to merge 2 commits into
segmentio:masterfrom
chrfalch:spm-support
Open

chrfalch wants to merge 2 commits into
segmentio:masterfrom
chrfalch:spm-support

Conversation

@chrfalch

@chrfalch chrfalch commented Nov 4, 2026

Copy link
Copy Markdown

Summary

React Native 0.88 can build apps with Swift Package Manager (SwiftPM). React Native 0.89 plans to make it the default. CocoaPods trunk is becoming read-only. @segment/sovran-react-native and @segment/analytics-react-native have no Package.swift, so SwiftPM apps cannot use them.

This PR has two commits, one for each package:

  • feat(sovran): add Swift Package Manager support
  • feat(core): add Swift Package Manager support

The sovran scope matches earlier commits such as fix(sovran): … (#1299).

sovran

  1. Add packages/sovran/Package.swift with one product, sovran_react_native. It has two targets: sovran_react_native for ios/Sovran.swift, and SovranObjC for ios/Sovran.m.
  2. Add packages/sovran/spm-headers/public/module.modulemap, an empty public module for SovranObjC.
  3. Add swiftpmConfig.name and ship the new files through the files list in packages/sovran/package.json.

core

  1. Add packages/core/Package.swift with one product, segment_analytics_react_native. It has two targets: one for ios/AnalyticsReactNative.swift, and SegmentAnalyticsObjC for ios/AnalyticsReactNative.m. The Swift target depends on sovran_react_native.
  2. Add packages/core/spm-support/React.swift. It imports React for the Swift code, because SwiftPM does not use the CocoaPods bridging header.
  3. Add packages/core/spm-headers/public/module.modulemap, an empty public module for SegmentAnalyticsObjC.
  4. Add swiftpmConfig.name, list @segment/sovran-react-native in swiftpmConfig.dependencies, and ship the new files through the files list in packages/core/package.json.

SwiftPM cannot compile Swift and Objective-C in one target, so each package has two targets. The product names are the pod names with underscores, because a hyphen is not valid in a Swift module name. Core's Swift code imports sovran_react_native, so sovran's product must keep that name.

The core Swift package includes ios/PrivacyInfo.xcprivacy as a resource. The podspec does not ship this file.

CocoaPods is unchanged. The podspecs and ios/ sources are untouched.

Release order

Core's SwiftPM manifest needs a sovran release that has Package.swift. The core range for sovran stays ^1.1.0. With deps.bump: 'satisfy' in multi-release.config.js, the release does not raise it. A SwiftPM app that resolves an older sovran stops at spm update with an error for sovran, because that release has no Package.swift. You may want to raise the range to the first sovran release with Package.swift. I left that choice to you.

Limits: The Swift packages need iOS 15.1, the minimum of React Native 0.88. The podspecs stay at iOS 11. No CI job here builds the Swift packages yet.
RFC: react-native-community/discussions-and-proposals#994

Test plan

In a new React Native 0.88.1 app, with both packages installed from the local checkout:

npx react-native spm add --deintegrate --yes
npx react-native spm update
xcodebuild -project ios/<App>.xcodeproj -scheme <App> -configuration Debug -destination "generic/platform=iOS Simulator" CODE_SIGNING_ALLOWED=NO build
xcodebuild -project ios/<App>.xcodeproj -scheme <App> -configuration Release -destination "generic/platform=iOS Simulator" CODE_SIGNING_ALLOWED=NO build

Before this change, spm update stopped for both packages because each mixes Swift and Objective-C sources. After it, add and update passed. Debug and Release ended with ** BUILD SUCCEEDED **.
Runtime check: I ran the built app on an iOS simulator. All four checks passed:

  • getContextInfo returned the OS, bundle ID, device model, and screen size.
  • Sovran.getConstants returned ON_STORE_ACTION.
  • A sovran store dispatch updated the state.
  • client.context showed the OS and the app.

Not run: a device build, the CocoaPods build, and the repo's Jest tests.

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.

1 participant