Conversation
selectPlacements now takes an array of RoktLayoutView placeholderNames only.
The map of placeholder name to findNodeHandle react tag is removed, together
with the native view-tag lookups behind it (viewRegistry_DEPRECATED on iOS,
UIManager.resolveView and NativeViewHierarchyManager on Android).
The native module interface now declares placeholders as Array<string>. A
map passed from plain JavaScript logs an error, and the placement is
requested without embedded views, so every platform behaves the same instead
of Android throwing and iOS dropping or misreading the argument. Both native
modules skip non-string entries. The Android name lookup is shared by both
architectures in MPRoktModuleImpl.
BREAKING CHANGE: selectPlacements no longer accepts
{ [placeholderName]: findNodeHandle(ref) }. Pass ['placeholderName'] instead;
earlier 3.x releases accept both forms, so apps can switch before upgrading.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
PR SummaryMedium Risk Overview In JavaScript, On iOS and Android across both architectures, native module signatures and implementations now accept arrays instead of dictionaries. All legacy view tag lookup logic (such as Reviewed by Cursor Bugbot for commit 5ba7575. Bugbot is set up for automated code reviews on this repo. Configure here. |
Why
Embedded placements can still be requested with a map of placeholder name to
findNodeHandleview tag. That form keeps the SDK on view-tag lookups React Native is removing (viewRegistry_DEPRECATEDon iOS,NativeViewHierarchyManagerandUIManager.resolveViewon Android), and integrations that use it can still read a tag before the view exists and fail to embed without an error. Name-based placeholders already cover every case the map did, including views that mount after the call. Once this lands,selectPlacementshas one way to embed a placement: an array ofRoktLayoutViewplaceholder names. This is a breaking change for apps that still pass the map; the release that ships the Swift Package Manager work is a major version for this reason.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. This is the seventh pull request in the series merging into the
workstation/spm-migrationbranch, which merges intomainonce the series is complete and ships in one release; the plan record is internal and cannot be linked here.What changes
Before:
placeholdersis a name array or a map of name to view tag. The wrapper turns both into a map, using0to mean "look up by name", and each native module resolves positive values as view tags.After:
placeholdersis an array of placeholder names, from the TypeScript type through the native module interface to both native modules.RoktPlaceholdersisstring[]. A map passed from plain JavaScript logs an error, and the placement is requested without embedded views. Without this check the platforms would disagree: Android would throw, and iOS would drop or misread the argument.resolvePlaceholders:and the wait for unmounted views read names only and skip non-string entries. The view-tag lookup and@synthesize viewRegistry_DEPRECATEDare removed.MPRoktModuleImpl, which skips non-string entries. The view-tag lookup (UIManager.resolveView,NativeViewHierarchyManager) is removed. The legacy architecture still usesaddUIBlockto run after pending UI work.Start reading at
js/rokt/rokt.ts, thenMPRoktModuleImpl.ktandRNMPRokt.mm. Unchanged on purpose: the name registry, the 2-second wait for unmounted views, andPlacementFailurefor dropped waits.Linked work
Depends on: the experimental
Package.swift(branchthomson-t/spm-06-package-swift) and the pull requests below it in this series; merge those first.Related: the pull request that added name-based placeholders, #410.
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, which must be a major version.Feature flags: none.
Turning it off: revert this pull request; the map form comes back in the next release.
What we watch: this repository's issues, for embedded placements that stop rendering after an upgrade, and the error
selectPlacements: placeholders must be an arrayin partner reports.Risks
Cannot resolve placeholderlogs.Risk class: medium, because this is a breaking API change.
Who
Written by: an automated coding agent (Claude Code), at an engineer's request.
Code reviewed before opening: an independent review agent reviewed the change before it was committed.
Design reviewed before opening: the requesting engineer approved removing the map form in the release that ships Swift Package Manager support, and chose the log-and-drop behaviour for a leftover map.
Decision this implements: the engineering decision on 2026-09-29 to ship the breaking placeholder change together with Swift Package Manager support; the record is internal and cannot be linked.
Checked: on 2026-09-30, with Xcode 27.0, an iOS 26.5 simulator and an Android emulator (API 36):
yarn test(jest and eslint),yarn buildandyarn build:plugin;./gradlew test ktlintCheck lintinandroid/.Podfile.lockis unchanged, and the Release build has one copy of each SDK class.PlacementFailureon iOS and Android.MP_USE_SPM=1): the sample builds in Release with one copy of each SDK class, all in the app binary.Not checked: overlay placements (they pass no placeholders, so that path is unchanged); React Native's Swift Package Manager mode; physical devices.
Size
Hand-written: 149 lines added and 263 removed in 14 files (55 added and 70 removed of them in tests).
Generated: none.
🤖 Generated with Claude Code