Conversation
|
CodeAnt AI is reviewing your PR. Thanks for using CodeAnt! 🎉We're free for open-source projects. if you're enjoying it, help us grow by sharing. Share on X · |
Review Summary by QodoFix React Native 0.79 compatibility with ReactCodegen support
WalkthroughsDescription• Support React Native 0.79+ with ReactCodegen module import • Add Objective-C++ TurboModule implementation for new architecture • Update podspec with install_modules_dependencies for codegen • Maintain backward compatibility with RN 0.77 and 0.78 Diagramflowchart LR
RN["React Native versions"]
RN -->|"RN ≥ 0.79"| ReactCodegen["ReactCodegen module"]
RN -->|"RN 0.78"| React_Codegen["React_Codegen module"]
RN -->|"RN ≤ 0.77"| RNUsercentricsModuleSpec["RNUsercentricsModuleSpec"]
ReactCodegen --> TurboModuleMM["TurboModule.mm C++ impl"]
React_Codegen --> NativeUsercentricsModuleSpec["NativeUsercentricsModuleSpec protocol"]
RNUsercentricsModuleSpec --> NativeUsercentricsSpec["NativeUsercentricsSpec protocol"]
TurboModuleMM --> getTurboModule["getTurboModule implementation"]
NativeUsercentricsModuleSpec --> getTurboModule
NativeUsercentricsSpec --> getTurboModule
File Changes1. ios/RNUsercentricsModule.swift
|
Code Review by Qodo
1. Fragile codegen header include
|
📝 WalkthroughWalkthroughAdds iOS TurboModule bridging for React Native New Architecture: an Objective-C++ thin wrapper exposing a C++ TurboModule, Swift conformance branches for multiple RN versions, and podspec updates to support conditional codegen dependencies and simplified header/search paths. Changes
Sequence Diagram(s)sequenceDiagram
participant JS as JavaScript
participant RN as RN TurboModule System
participant ObjCxx as ObjC++ Bridge
participant Swift as RNUsercentricsModule (Swift)
JS->>RN: call native method on TurboModule
RN->>ObjCxx: resolve TurboModule via getTurboModule(params)
ObjCxx->>Swift: forward invoker / provide module instance
Swift-->>RN: return module implementation (as Any / JS-facing object)
RN-->>JS: deliver result
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
PR Summary: Upgrade iOS native module to support RN new-architecture naming changes (RN 0.78/0.79) and ensure TurboModule codegen/C++ build flags work with Expo/prebuild.
Notes/impact:
|
Nitpicks 🔍
|
| #if canImport(React_Codegen) | ||
| // RN 0.78: codegen-generated protocol | ||
| extension RNUsercentricsModule: NativeUsercentricsModuleSpec { | ||
| func getTurboModule(jsInvoker: RCTJSInvoker) -> Any { | ||
| return self | ||
| } | ||
| } | ||
| #elseif canImport(RNUsercentricsModuleSpec) | ||
| // RN ≤ 0.77 | ||
| extension RNUsercentricsModule: NativeUsercentricsSpec { | ||
| func getTurboModule(jsInvoker: RCTJSInvoker) -> Any { | ||
| return self | ||
| } |
There was a problem hiding this comment.
[CRITICAL_BUG] The extension implements/declares conformance to NativeUsercentricsModuleSpec which does not match the generated protocol name in the project reference (NativeUsercentricsSpec). This will cause a compile-time error (type not found). Replace NativeUsercentricsModuleSpec with the correct generated protocol (NativeUsercentricsSpec) or detect the correct symbol via canImport and adapt accordingly. Also run a clean build to verify the generated module/protocol name for the targeted RN versions.
#if RCT_NEW_ARCH_ENABLED
#if canImport(React_Codegen)
// RN 0.78: codegen-generated protocol
extension RNUsercentricsModule: NativeUsercentricsSpec {
func getTurboModule(jsInvoker: RCTJSInvoker) -> Any {
return self
}
}
#elseif canImport(RNUsercentricsModuleSpec)
// RN ≤ 0.77
extension RNUsercentricsModule: NativeUsercentricsSpec {
func getTurboModule(jsInvoker: RCTJSInvoker) -> Any {
return self
}
}
#endif
#else
extension RNUsercentricsModule: RCTBridgeModule {}
#endif| #if canImport(ReactCodegen) | ||
| // RN ≥ 0.79: getTurboModule: implemented in RNUsercentricsModule+TurboModule.mm (do not import ReactCodegen in Swift — C++ module) | ||
| #elseif canImport(React_Codegen) | ||
| // RN 0.78 | ||
| import React_Codegen | ||
| #elseif canImport(RNUsercentricsModuleSpec) |
There was a problem hiding this comment.
[REFACTORING] The preprocessor branch uses canImport(ReactCodegen) (no underscore) followed by canImport(React_Codegen). The module name historically used by RN codegen is 'React_Codegen' (with underscore). The top-level canImport(ReactCodegen) branch is ambiguous and only contains a comment (no import). Consider removing the canImport(ReactCodegen) check (or correct it) and consolidate logic so it's explicit which RN versions import which module. This avoids confusion and accidental dead branches during compilation.
#if RCT_NEW_ARCH_ENABLED
// RN ≥ 0.79: getTurboModule: implemented in RNUsercentricsModule+TurboModule.mm (do not import ReactCodegen in Swift — C++ module)
#if canImport(React_Codegen)
// RN 0.78
import React_Codegen
#elif canImport(RNUsercentricsModuleSpec)
// RN ≤ 0.77
import RNUsercentricsModuleSpec
#endif
#endif| - (std::shared_ptr<facebook::react::TurboModule>)getTurboModule: | ||
| (const facebook::react::ObjCTurboModule::InitParams &)params { | ||
| return std::make_shared<facebook::react::NativeUsercentricsModuleSpecJSI>(params); | ||
| } |
There was a problem hiding this comment.
[CRITICAL_BUG] The code returns std::make_sharedfacebook::react::NativeUsercentricsModuleSpecJSI(params). That generated C++/JSI type may not exist (name varies by RN/codegen). This will fail linking/compilation if the generated JSI class name or header differs. Actionable options: 1) Verify the exact generated C++ type name and include the correct generated header from codegen, or 2) if relying on an ObjC TurboModule wrapper, return an ObjCTurboModule-backed TurboModule (or nullptr) until the generated JSI class is available. At minimum, add a compile-time guard/comment and test building with RN 0.78/0.79 to confirm the correct symbol.
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
(const facebook::react::ObjCTurboModule::InitParams &)params {
#if __has_include(<ReactCodegen/RNUsercentricsModule/RNUsercentricsModule.h>)
return std::make_shared<facebook::react::NativeUsercentricsModuleSpecJSI>(params);
#else
// Fallback for configurations where the generated JSI type is not available
return nullptr;
#endif
}| # Required for TurboModules RN 0.78+: injects codegen dependencies (ReactCodegen, etc.) | ||
| if defined?(install_modules_dependencies) | ||
| install_modules_dependencies(s) | ||
| end |
There was a problem hiding this comment.
[CRITICAL_BUG] The podspec now calls install_modules_dependencies(s) when defined to inject codegen dependencies, but it no longer provides a fallback header_search_paths addition for environments where install_modules_dependencies isn't defined (older RN versions or custom prebuild flows). This can lead to missing React-Codegen / React-Fabric headers and broken iOS builds. Actionable fix: add a fallback branch that appends the React-Fabric/React-Codegen header paths (the previously removed entries) when install_modules_dependencies is not defined, or explicitly check supported RN versions and document that install_modules_dependencies must exist in the consuming project.
# Required for TurboModules RN 0.78+: injects codegen dependencies (ReactCodegen, etc.)
if defined?(install_modules_dependencies)
install_modules_dependencies(s)
else
# Fallback for projects without install_modules_dependencies (older RN / custom setups)
header_search_paths += [
'$(PODS_ROOT)/Headers/Public/React-Fabric',
'$(PODS_ROOT)/Headers/Public/React-Codegen',
'$(PODS_CONFIGURATION_BUILD_DIR)/React-Codegen/React_Codegen.framework/Headers',
'$(PODS_CONFIGURATION_BUILD_DIR)/React-Fabric/React_Fabric.framework/Headers'
]
end
# C++ configuration (compatible with Expo prebuild and New Architecture)
base_cpp_flags = {
'CLANG_CXX_LANGUAGE_STANDARD' => 'c++20',
'CLANG_CXX_LIBRARY' => 'libc++',
'OTHER_CPLUSPLUSFLAGS' => '-std=c++20 -stdlib=libc++ $(inherited)',
'CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER' => 'NO',
'CLANG_WARN_DOCUMENTATION_COMMENTS' => 'NO',
'GCC_WARN_INHIBIT_ALL_WARNINGS' => 'YES',
'CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES' => 'YES',
'DEFINES_MODULE' => 'YES',
'USE_HEADERMAP' => 'YES',
'ALWAYS_SEARCH_USER_PATHS' => 'NO'
}
base_cpp_flags['HEADER_SEARCH_PATHS'] = header_search_paths.map { |path| "\"#{path}\"" }.join(' ')|
Reviewed up to commit:8a1d201fd92a0f8418655677172b10aa970f3654 Additional Suggestionios/RNUsercentricsModule.swift, line:236-239The getTurboModule(jsInvoker: RCTJSInvoker) -> Any signature is used here for TurboModule conformance. Generated protocol signatures and types (RCTJSInvoker) can vary between RN versions. Verify that RCTJSInvoker is available to Swift under the chosen canImport branches and that the method signature matches the generated protocol for each RN version you intend to support. If the type or signature differs, adapt the declaration to match the generated header or provide conditional compilation that aligns with the correct generated protocol.#if RCT_NEW_ARCH_ENABLED
#if canImport(React_Codegen)
extension RNUsercentricsModule: NativeUsercentricsSpec {
func getTurboModule(jsInvoker: RCTJSInvoker) -> Any {
return self
}
}
#elif canImport(RNUsercentricsModuleSpec)
extension RNUsercentricsModule: NativeUsercentricsSpec {
func getTurboModule(jsInvoker: RCTJSInvoker) -> Any {
return self
}
}
#endif
#else
extension RNUsercentricsModule: RCTBridgeModule {}
#endif |
| // Header generated by the app's codegen (ReactCodegen pod; path may vary by RN version) | ||
| #if __has_include(<ReactCodegen/RNUsercentricsModule/RNUsercentricsModule.h>) | ||
| #import <ReactCodegen/RNUsercentricsModule/RNUsercentricsModule.h> | ||
| #else | ||
| #import "RNUsercentricsModule/RNUsercentricsModule.h" | ||
| #endif |
There was a problem hiding this comment.
1. Fragile codegen header include 🐞 Bug ⛯ Reliability
The TurboModule ObjC++ file imports a codegen-generated header via either <ReactCodegen/...> or a
quoted include ("RNUsercentricsModule/..."). The podspec no longer adds explicit
React-Codegen/ReactCodegen header search paths and only injects codegen dependencies when
install_modules_dependencies is defined, so some new-arch builds can fail with missing-header
errors.
Agent Prompt
### Issue description
`RNUsercentricsModule+TurboModule.mm` requires a codegen header but the podspec no longer guarantees header search paths/dependencies unless `install_modules_dependencies` is defined and effective. This can lead to `file not found` build errors for new-arch consumers.
### Issue Context
Header locations differ across RN versions (`ReactCodegen` vs `React-Codegen`), and consumers may not always have the helper available (custom Podfiles/build setups).
### Fix Focus Areas
- ios/RNUsercentricsModule+TurboModule.mm[13-18]
- react-native-usercentrics.podspec[23-55]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
|
CodeAnt AI finished reviewing your PR. |
…ency-react-codegen
|
CodeAnt AI is running Incremental review Thanks for using CodeAnt! 🎉We're free for open-source projects. if you're enjoying it, help us grow by sharing. Share on X · |
|
CodeAnt AI Incremental review completed. |
User description
Summary by CodeRabbit
New Features
Chores
CodeAnt-AI Description
Fix iOS build and TurboModule registration across React Native 0.77–0.79+
What Changed
Impact
✅ Builds on RN 0.79+✅ Fewer iOS build failures during prebuild✅ Native module registers with New Architecture (TurboModule)💡 Usage Guide
Checking Your Pull Request
Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.
Talking to CodeAnt AI
Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:
This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.
Example
Preserve Org Learnings with CodeAnt
You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:
This helps CodeAnt AI learn and adapt to your team's coding style and standards.
Example
Retrigger review
Ask CodeAnt AI to review the PR again, by typing:
Check Your Repository Health
To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.