Skip to content

Add a Swift Package Manager manifest for React Native SPM apps - #97

Draft
ofalvai wants to merge 1 commit into
remove-vendored-jwt-base64from
spm-package-manifest
Draft

ofalvai wants to merge 1 commit into
remove-vendored-jwt-base64from
spm-package-manifest

Conversation

@ofalvai

@ofalvai ofalvai commented Oct 27, 2026 •

Copy link
Copy Markdown
Collaborator

Part 4 of the stack: #94 → #95 → #96 → this PR.

RN 0.89 makes Swift Package Manager the default for iOS apps. RN 0.88 already autolinks a library that ships its own Package.swift. This PR adds that manifest, so CodePush works in an SPM app. CocoaPods consumers see no change.

What changes

  • A Package.swift at the repository root. The HDiffPatch sources are in shared/, outside ios/, and an SPM target path cannot leave the package root, so the manifest needs to be in the root.
  • Declare ZipArchive as a remote dependency (it's packaged both as a Pod and as a Swift package)
  • The podspec glob for ios/CodePush/ goes back to *.{h,m}. SwiftPM builds that directory as an Objective-C target and rejects Swift files in it. The podspec now follows the same rule.

Why CodePushCore has two manifests

#94 added ios/CodePushCore/Package.swift, and it is only for tests: npm run test:unit:ios:core uses it to run the verifier tests on a simulator. The root manifest cannot do this, because its ReactNative dependency resolves only when the autolinker loads the manifest from inside an app. Both manifests point at the same Sources/ directory, so the code exists only once.

Open questions

  • E2E coverage. This PR does not run the E2E suite in an SPM app.

🤖 Generated with Claude Code

@ofalvai
ofalvai added this pull request to stack #98 October 27, 2026 20:52
@ofalvai ofalvai changed the title spm package manifest Add a Swift Package Manager manifest for React Native SPM apps Oct 27, 2026
Copilot AI balanced review requested due to automatic review settings October 27, 2026 20:56
@ofalvai
ofalvai force-pushed the spm-package-manifest branch from 0041dff to 596ea8b Compare October 27, 2026 20:56

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Changes recommended

The unconditional local dependency in Package.swift blocks package resolution for apps using RN_SPM_REMOTE_URL or a custom --xcframeworks-path when the default build/xcframeworks package is absent.

1 open issue
What changed in this PR

Adds Swift Package Manager integration for CodePush in React Native apps while preserving CocoaPods support.

Changes:

  • Defines SwiftPM targets for the native bridge, Swift core, and binary patching code.
  • Adds autolinking metadata and public header exposure.
  • Adjusts native imports for SwiftPM and narrows the CocoaPods source glob.
File Description
Package.swift Defines products, targets, dependencies, and native linker settings.
package.json Adds the CodePush SwiftPM autolinking name.
ios/​CodePush/​include/​module.modulemap Exposes the CodePush module to consumers.
ios/​CodePush/​include/​CodePush/​CodePush.h Adds a forwarding header for public imports.
ios/​CodePush/​CodePushUpdateUtils.m Imports the separate Swift core module under SwiftPM.
ios/​CodePush/​CodePushPackage.m Selects the ZipArchive import for SwiftPM.
CodePush.podspec Removes Swift files from the bridge-directory source glob.

Review effort: Balanced

Comment thread Package.swift
.library(name: "CodePush", targets: ["CodePush"]),
],
dependencies: [
.package(name: "ReactNative", path: reactNativePackagePath),
@ofalvai
ofalvai force-pushed the spm-package-manifest branch from 596ea8b to fc6051f Compare October 28, 2026 10:31
@ofalvai
ofalvai force-pushed the spm-package-manifest branch 2 times, most recently from cf02fa1 to 5177ea3 Compare October 28, 2026 10:50
Comment thread CodePush.podspec
s.libraries = 'z', 'bz2'
s.source_files = [
'ios/CodePush/*.{h,m,swift}',
'ios/CodePush/*.{h,m}',

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

This is meant to prevent accidentally picking up .swift files from the main CodePush source dir. New Swift code should go to CodePushCore

React Native 0.88 autolinks a library that ships its own Package.swift.
The manifest sits at the package root because the HDiffPatch sources in
shared/ are outside ios/, and target paths cannot leave the package root.

The React header products come from the app's ReactNative package. The
autolinker loads the manifest through build/generated/autolinking/libs/CodePush,
so the relative path ../../../../xcframeworks reaches it in every app. This
is the same path that `react-native spm scaffold` emits, and that
react-native-safe-area-context ships.

Targets: CodePush (Objective-C), CodePushCore (Swift) and CodePushHDiffPatch
(C, same defines as the podspec). ZipArchive is a remote dependency. A
custom module map is necessary because SwiftPM rejects an umbrella header
next to the vendored SSZipArchive directory.

The podspec flow does not change: SWIFT_PACKAGE is only defined by SwiftPM.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ofalvai
ofalvai force-pushed the spm-package-manifest branch from 5177ea3 to 643d0ed Compare October 28, 2026 12:58
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.

2 participants