Skip to content

refactor(ios): resolve mParticle and RoktContracts headers through one private header - #422

Open
thomson-t wants to merge 1 commit into
thomson-t/spm-01-duplicate-sdk-warningfrom
thomson-t/spm-02-sdk-import-header
Open

thomson-t wants to merge 1 commit into
thomson-t/spm-01-duplicate-sdk-warningfrom
thomson-t/spm-02-sdk-import-header

Conversation

@thomson-t

@thomson-t thomson-t commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

Why

This package finds the mParticle and Rokt headers with a block of fallback rules that was copied, slightly differently, into five files. The next change in this series, an opt-in Swift Package Manager mode, needs one more rule, and adding it five times invites the copies to drift apart. Once this lands, the rules live in one place, and apps see no difference: the files compile against exactly the same headers as before.

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 second of eight pull requests, all merging into the workstation/spm-migration branch, which merges into main once the series is complete, and shipping together in one release; the plan record is internal and cannot be linked here.

What changes

Before: RNMParticle.mm, RNMPRokt.mm, RoktEventManager.mm, RoktLayoutManager.m and RoktNativeLayoutComponentView.h each had their own __has_include chain, and RoktLayoutManager.m also used @import RoktContracts.

After: they all #import "RNMPSDKImports.h", which tries, in order:

  1. CocoaPods: <mParticle_Apple_SDK_ObjC/…> and <RoktContracts/RoktContracts-Swift.h>;
  2. a manually embedded xcframework: <mParticle_Apple_SDK/…> and <RoktContracts/RoktContracts.h>;
  3. flat headers on the search path ("mParticle.h", "RoktContracts-Swift.h"), which the next pull request uses;
  4. a module import, as a last resort that works in .m files only.

The podspec is unchanged. The header is also listed in ios/RNMParticle.xcodeproj, the way the placeholder registry files were. No documentation change is needed.

Linked work

Depends on: the previous pull request in this series, which adds the debug-build duplicate-SDK warning (branch thomson-t/spm-01-duplicate-sdk-warning); merge that first.
Unblocks: the opt-in Swift Package Manager mode (branch thomson-t/spm-03-spm-core-mode).

Rollout

Path: this merges into workstation/spm-migration, not main, so nothing reaches main or a release until the whole series has merged there and that branch is merged into main. It then ships in the next release.
Feature flags: none.
Turning it off: a published version cannot be recalled. Reverting this pull request and releasing again restores the per-file blocks in the next version.
What we watch: this repository's issues and CI, for header-not-found build errors in any integration mode.

Risks

  • A file could pick up a different header than before and fail to build in some integration mode; prevented because the first two branches match the old chains exactly, and the default CocoaPods mode produced an identical Podfile.lock and a passing build, archive and test run; we would see "file not found" build errors reported against that release.
  • Files now see more of the SDK's headers than they used to (for example, RNMParticle.mm now also sees the Rokt headers); contained because these are the same public SDK headers the package already depends on, and nothing is redeclared; we would see a duplicate-declaration build error.
  • The module-import fallback cannot compile in Objective-C++ files; not addressed, because it is reached only when none of the three header layouts is present, which no supported integration produces; we would see a module import error instead of "file not found".

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.
Code reviewed before opening: an independent review agent reviewed the change before it was committed.
Design reviewed before opening: the requesting engineer approved the migration plan, which specifies this header and its branch order.
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-28, with Xcode 27.0 on an iOS 26.5 simulator, the sample app (React Native 0.84, New Architecture) in its default CocoaPods mode:

  • pod install gave an identical Podfile.lock;
  • Debug tests: 38 run, 0 failures;
  • a Release build and an unsigned archive succeeded;
  • the archived app holds exactly one copy of each SDK class;
  • embedded placements (by name and by legacy tag) and an overlay placement rendered, with the full event sequence.
    Not checked: the Old Architecture; tvOS; a manually embedded xcframework. CI, which builds with Xcode 16, passed on this pull request.

Size

Hand-written: 35 lines added and 48 removed in 7 files.
Generated: none.

🤖 Generated with Claude Code

…e private header

Five files carried their own copy of the __has_include chain that finds
the mParticle and RoktContracts headers. They now import
RNMPSDKImports.h, which tries CocoaPods, a manual xcframework, flat
headers on the search path (for the upcoming opt-in Swift Package
Manager mode), then a module import. The podspec is unchanged, and
Podfile.lock is identical in the default CocoaPods mode.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@thomson-t
thomson-t added this pull request to stack #427 September 29, 2026 21:25
@thomson-t
thomson-t marked this pull request as ready for review September 30, 2026 13:19
@thomson-t
thomson-t requested a review from a team as a code owner September 30, 2026 13:19
Copilot AI balanced review requested due to automatic review settings September 30, 2026 13:19
@cursor

cursor Bot commented Sep 30, 2026 •

Copy link
Copy Markdown

PR Summary

Low Risk
Internal header import consolidation with no changes to runtime behavior or public APIs.

Overview
Consolidates duplicate header import logic and __has_include fallback chains for mParticle and RoktContracts into a single shared private header, RNMPSDKImports.h.

Replaces the repeated import blocks across RNMParticle.mm, RNMPRokt.mm, RoktEventManager.mm, RoktLayoutManager.m, and RoktNativeLayoutComponentView.h with the unified header, and adds RNMPSDKImports.h to the Xcode project references. The new header supports standard CocoaPods, embedded xcframeworks, flat search paths for SPM compatibility, and fallback @import modules.

Reviewed by Cursor Bugbot for commit 6676416. Bugbot is set up for automated code reviews on this repo. Configure here.

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

The intended private header is exported publicly by the current CocoaPods specification.

Review effort: Balanced
Findings: 1 Medium severity

Open (1)
What changed in this PR

Centralizes iOS SDK header resolution to prepare for Swift Package Manager support.

Changes:

  • Adds shared fallback import logic.
  • Replaces five duplicated import chains.
  • Registers the header in the Xcode project.
File Description
ios/​RNMParticle/​RNMPSDKImports.h Defines centralized SDK imports.
ios/​RNMParticle/​RNMParticle.mm Uses shared imports.
ios/​RNMParticle/​RNMPRokt.mm Uses shared imports.
ios/​RNMParticle/​RoktEventManager.mm Uses shared imports.
ios/​RNMParticle/​RoktLayoutManager.m Uses shared imports.
ios/​RNMParticle/​RoktNativeLayoutComponentView.h Uses shared imports.
ios/​RNMParticle.xcodeproj/​project.pbxproj Registers the new header.

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

@@ -0,0 +1,28 @@
// Private: the mParticle and RoktContracts headers, for every way an app can supply the SDKs.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

That is right for this PR on its own. #425, later in this stack, adds s.private_header_files = 'ios/**/*.h' to the podspec, which makes every implementation header private, this one included. The stack merges into workstation/spm-migration as a whole before anything reaches main, so the in-between state is never released.

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