Summary
react-native-ios-utilities@5.2.0 references RCTRootContentView in RCTView+Helpers.swift, but RN 0.85 (Expo SDK 56) builds with RCT_REMOVE_LEGACY_ARCH=1 by default — RCTRootContentView is wrapped in #ifndef RCT_REMOVE_LEGACY_ARCH in React Native, so it never gets compiled into React.framework. The link step then fails with:
Undefined symbols for architecture arm64:
"_OBJC_CLASS_$_RCTRootContentView", referenced from:
in libreact-native-ios-utilities.a[48](RCTView+Helpers.o)
ld: symbol(s) not found for architecture arm64
This blocks any new-arch / Expo SDK 56 app from building when react-native-ios-utilities (or downstream react-native-ios-context-menu) is in the dependency tree.
Repro
- React Native 0.85.x with the new architecture (or Expo SDK 56, which sets
RCT_REMOVE_LEGACY_ARCH=1 unconditionally during prebuild).
react-native-ios-utilities@5.2.0 as a dep (direct or transitive via react-native-ios-context-menu@3.2.1).
- Build the iOS target — link step fails with the undefined symbol above.
Cause
apple/Sources/Extensions+Helpers/RCTView+Helpers.swift line 28 declares closestParentReactContentView: RCTRootContentView? and references RCTRootContentView.self. Line 55 chains through it. The property is otherwise unused anywhere in this package or in react-native-ios-context-menu, so it's effectively dead code that drags in a legacy-arch symbol.
Suggested fix
Stub the property + its single fallback caller so the symbol isn't referenced. Diff:
diff --git a/ios/Sources/Extensions+Helpers/RCTView+Helpers.swift b/ios/Sources/Extensions+Helpers/RCTView+Helpers.swift
@@ -25,16 +25,10 @@ public extension RCTView {
return rootView.recursivelyFindSubview(whereType: targetType);
};
- var closestParentReactContentView: RCTRootContentView? {
- let targetType = RCTRootContentView.self;
-
- if let match = self.recursivelyFindParentView(whereType: targetType) {
- return match;
- };
-
- guard let rootView = self.rootViewForCurrentWindow else { return nil };
- return rootView.recursivelyFindSubview(whereType: targetType);
- };
+ // RCTRootContentView is excluded when RCT_REMOVE_LEGACY_ARCH=1 (default in
+ // RN 0.85+ / Expo SDK 56). Property is unused by this package and downstream,
+ // so stub to nil to avoid an undefined-symbol linker error.
+ var closestParentReactContentView: AnyObject? { nil };
var reactTouchHandlers: [RCTTouchHandler]? {
self.gestureRecognizers?.compactMap {
@@ -58,6 +52,8 @@ public extension RCTView {
currentView = superview;
};
- return closestParentReactContentView?.reactTouchHandlers?.first;
+ // Legacy `closestParentReactContentView` chain returned nil under new arch
+ // (RCTRootContentView excluded by RCT_REMOVE_LEGACY_ARCH=1); inline that.
+ return nil;
};
};
A more proper fix could keep the property but guard the body with #if !RCT_REMOVE_LEGACY_ARCH / use #if canImport or runtime NSClassFromString("RCTRootContentView") lookup. The stub above is the minimal-surface-area change that unblocks consumers on RN 0.85+.
Environment
- Xcode 26.5
- iOS Simulator 26.3 / 26.5
- React Native 0.85.3
- Expo SDK 56.0.11
react-native-ios-utilities 5.2.0
react-native-ios-context-menu 3.2.1 (downstream consumer)
Happy to open a PR if helpful.
Summary
react-native-ios-utilities@5.2.0referencesRCTRootContentViewinRCTView+Helpers.swift, but RN 0.85 (Expo SDK 56) builds withRCT_REMOVE_LEGACY_ARCH=1by default —RCTRootContentViewis wrapped in#ifndef RCT_REMOVE_LEGACY_ARCHin React Native, so it never gets compiled intoReact.framework. The link step then fails with:This blocks any new-arch / Expo SDK 56 app from building when
react-native-ios-utilities(or downstreamreact-native-ios-context-menu) is in the dependency tree.Repro
RCT_REMOVE_LEGACY_ARCH=1unconditionally during prebuild).react-native-ios-utilities@5.2.0as a dep (direct or transitive viareact-native-ios-context-menu@3.2.1).Cause
apple/Sources/Extensions+Helpers/RCTView+Helpers.swiftline 28 declaresclosestParentReactContentView: RCTRootContentView?and referencesRCTRootContentView.self. Line 55 chains through it. The property is otherwise unused anywhere in this package or inreact-native-ios-context-menu, so it's effectively dead code that drags in a legacy-arch symbol.Suggested fix
Stub the property + its single fallback caller so the symbol isn't referenced. Diff:
A more proper fix could keep the property but guard the body with
#if !RCT_REMOVE_LEGACY_ARCH/ use#if canImportor runtimeNSClassFromString("RCTRootContentView")lookup. The stub above is the minimal-surface-area change that unblocks consumers on RN 0.85+.Environment
react-native-ios-utilities5.2.0react-native-ios-context-menu3.2.1 (downstream consumer)Happy to open a PR if helpful.