-
Notifications
You must be signed in to change notification settings - Fork 12
feat: fabric support #167
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: fabric support #167
Conversation
WalkthroughMigrates the library to React Native’s New Architecture and TurboModules: adds TurboReactPackage/Kotlin wiring, JNI/C++ stubs and CMake targets, TypeScript TurboModule typings and codegen, updates Android/iOS build configs and sample apps, and introduces scripts for codegen, packaging and iOS build fixes. Changes
Sequence Diagram(s)sequenceDiagram
participant JS as JavaScript/TS
participant TMReg as TurboModuleRegistry
participant Native as NativeModules
participant RNHost as ReactNativeHost
participant TRP as TurboReactPackage
participant Kt as KotlinModule
participant JNI as JNI/C++
JS->>TMReg: get('RNUsercentricsModule')
alt TurboModule available
TMReg-->>JS: TurboModule proxy
else
JS->>Native: NativeModules.RNUsercentricsModule
Native-->>JS: legacy module
end
TMReg->>RNHost: resolve package
RNHost->>TRP: getModule(name)
TRP->>Kt: instantiate RNUsercentricsModule
Kt->>JNI: (optional native calls)
JNI->>JNI: RNUsercentricsModule_ModuleProvider() (placeholder)
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Areas requiring extra attention:
Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ 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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 10
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (4)
scripts/publish-local.sh (1)
7-7: Harden packaging: enable pipefail, parse npm JSON, and verify file exists.Without
pipefail, a failingnpm packcan look successful and produce a bogus filename. Parse--jsoninstead and assert the tarball exists.-7 set -e +7 set -euo pipefail -92 PACKAGE_FILE=$(npm pack 2>&1 | tail -1) +92 PACKAGE_FILE="$(npm pack --json | jq -r '.[0].filename')" +93 # Fallback if --json is unsupported (older npm) +94 if [ -z "$PACKAGE_FILE" ] || [[ "$PACKAGE_FILE" == "null" ]]; then +95 PACKAGE_FILE="$(npm pack 2>&1 | rg -n --no-line-number -o '[^[:space:]]+\.tgz$' | tail -1 || true)" +96 fi +97 if [ -z "$PACKAGE_FILE" ] || [ ! -f "$PACKAGE_FILE" ]; then +98 print_error "Failed to create npm package (no .tgz produced)." +99 exit 1 +100 fi -101 # Get absolute path of the package (macOS compatible) -102 PACKAGE_PATH="$(pwd)/$PACKAGE_FILE" +101 # Get absolute path of the package (macOS compatible) +102 PACKAGE_PATH="$(pwd)/$PACKAGE_FILE" +103 # Sanity check +104 [ -f "$PACKAGE_PATH" ] || { print_error "Package path not found: $PACKAGE_PATH"; exit 1; }Also applies to: 92-92, 101-103
package.json (3)
95-102: Move tool/runtime-internal packages out of dependencies.These should not be runtime deps of a library; they bloat consumers and can conflict with RN.
- Remove hermes-engine from dependencies (RN provides Hermes).
- Remove npm and install from dependencies; if needed, devDependencies or scripts only.
"dependencies": { - "hermes-engine": "^0.11.0", - "install": "^0.13.0", - "npm": "^11.6.0", "react-native-safe-area-context": "^5.6.1", "react-native-screens": "^4.16.0", "react-native-webview": "^13.16.0" },
12-19: Restore exclusion of android/build to prevent publishing generated build artifacts.The
prepublishOnlyscript runsnode scripts/generate-codegen-jni.js, which creates files underandroid/build/generated/source/codegen/jni. The currentfilesarray includes"android"but lacks the"!android/build"exclusion, so these generated artifacts will be published in the npm tarball.Apply this diff:
"files": [ "android", "ios", "lib", "src", "react-native-usercentrics.podspec", "react-native.config.js", + "!android/build", "!.DS_Store",
47-68: Replacereact-native-codegenwith@react-native/codegenand align version to match React Native 0.79.x.The package.json currently specifies the legacy
react-native-codegen@^0.0.7, but for React Native 0.79.x, use@react-native/codegen, version that matches your RN release (e.g. @react-native/[email protected]).Update devDependencies:
- "react-native-codegen": "^0.0.7", + "@react-native/codegen": "^0.79.0",
🧹 Nitpick comments (13)
sample/scripts/test-ios-build.sh (3)
36-41: Consider removing or conditionally enabling the-quietflag to improve build debugging.The
-quietflag suppresses build output, which makes it harder to diagnose compilation failures. For a test script, verbose output can be valuable for CI/CD logs and developer troubleshooting.Apply this diff to remove the
-quietflag:xcodebuild build \ -workspace sample.xcworkspace \ -scheme sample \ -destination "platform=iOS Simulator,id=$SIMULATOR" \ -configuration Debug \ - -quiet +Alternatively, make it conditional:
XCODEBUILD_FLAGS="${XCODEBUILD_FLAGS:--quiet}" xcodebuild build \ -workspace sample.xcworkspace \ -scheme sample \ -destination "platform=iOS Simulator,id=$SIMULATOR" \ -configuration Debug \ $XCODEBUILD_FLAGS
1-49: Addset -eat the beginning of the script to fail fast on errors.Currently, if any command fails (e.g.,
pod install), the script continues executing, potentially masking the root cause. Addingset -eensures the script exits immediately on the first error.Apply this diff to add early error handling:
#!/bin/bash +set -e # Script to test iOS compilation after React-logger fixesThis ensures robust error handling without manually adding
|| exit 1to every command.
44-45: Avoid hardcoding version references in the success message, as they become stale.Lines 44–45 reference "Xcode 26 + React Native 0.79," which may not reflect the actual versions being tested and could confuse future developers.
Consider removing or parameterizing the version reference:
- echo "✅ Compilation successful! React-logger fixes worked." - echo "🎉 Project ready for development with Xcode 26 + React Native 0.79!" + echo "✅ Compilation successful! React-logger fixes worked." + echo "🎉 Project ready for development!"sample/android/app/src/main/java/com/usercentrics/reactnativesdk/sample/MainApplication.kt (2)
17-23: Defer host creation to reduce cold-start work.Make reactNativeHost lazy to avoid instantiating before it’s needed. No behavior change; small startup win.
- override val reactNativeHost: ReactNativeHost = - object : DefaultReactNativeHost(this) { + override val reactNativeHost: ReactNativeHost by lazy(LazyThreadSafetyMode.NONE) { + object : DefaultReactNativeHost(this) { override fun getPackages(): List<ReactPackage> = PackageList(this).packages.apply { // Packages that cannot be autolinked yet can be added manually here, for example: // add(MyReactNativePackage()) } override fun getJSMainModuleName(): String = "index" override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED - } + } + }Also applies to: 25-31
33-34: Optional: cache ReactHost.getDefaultReactHost likely memoizes, but if not, prefer lazy to ensure a single instance.
- override val reactHost: ReactHost - get() = getDefaultReactHost(applicationContext, reactNativeHost) + override val reactHost: ReactHost by lazy(LazyThreadSafetyMode.NONE) { + getDefaultReactHost(applicationContext, reactNativeHost) + }If the current RN version guarantees memoization, feel free to keep as-is.
sample/ios/sample.xcodeproj/project.pbxproj (2)
374-384: Header search paths: only needed if you keep legacy <React/...> imports.Given RN’s modular frameworks, prefer guarded, module‑specific imports (React_NativeModulesApple, React_Fabric) in the bridging header and avoid expanding HEADER_SEARCH_PATHS further. If you must keep <React/...>, add a path to the umbrella React headers produced by your Pods setup (e.g., …/React.framework/Headers) to both Debug/Release configs.
Please confirm which of these exists in your Pods:
- Pods/.../React.framework/Headers
- Pods/.../React-Core/React.framework/Headers
- Pods/.../Headers/Public/React
Also applies to: 459-469
267-267: Empty DEVELOPMENT_TEAM blocks device builds.Optional: set DEVELOPMENT_TEAM for Debug so the sample can run on a device. Simulators are unaffected.
If you want, I can prepare a small xcconfig overlay to inject your team ID locally without committing it.
sample/ios/sample/AppDelegate.swift (1)
12-20: Use the two-argjsBundleURL(..., fallbackResource: nil)for RN API stability.Minor: this avoids signature drift across RN versions and is equivalent in behavior.
- guard let bundleURL = RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index") else { + guard let bundleURL = RCTBundleURLProvider.sharedSettings() + .jsBundleURL(forBundleRoot: "index", fallbackResource: nil) else { fatalError("Unable to find bundle URL") }sample/ios/Podfile (3)
27-32: Remove trailing comma after last arg inuse_react_native!.Minor Ruby style fix (and matches linter hint).
use_react_native!( :path => config[:reactNativePath], :hermes_enabled => true, - :fabric_enabled => $RCT_NEW_ARCH_ENABLED, - :new_arch_enabled => $RCT_NEW_ARCH_ENABLED, + :fabric_enabled => $RCT_NEW_ARCH_ENABLED, + :new_arch_enabled => $RCT_NEW_ARCH_ENABLED )
63-66: Do not disable all compiler warnings globally.
GCC_WARN_INHIBIT_ALL_WARNINGS = YEShides signal on real issues across all pods. Prefer addressing specific warnings (you already handle quoted includes) or scope to targets that truly need it.- config.build_settings['GCC_WARN_INHIBIT_ALL_WARNINGS'] = 'YES' + # Leave compiler warnings enabled; handle specific noisy cases instead. + # config.build_settings['GCC_WARN_INHIBIT_ALL_WARNINGS'] = 'YES'
67-69: Be cautious forcing C++20 for every Pod.Some pods pin to C++17 and will fail with C++20. If not strictly required, omit or scope to targets that need it (e.g., React-Core, hermes).
- config.build_settings['CLANG_CXX_LANGUAGE_STANDARD'] = 'c++20' - config.build_settings['CLANG_CXX_LIBRARY'] = 'libc++' + # If a specific pod requires C++20, set it on that target only. + # config.build_settings['CLANG_CXX_LANGUAGE_STANDARD'] = 'c++20' + config.build_settings['CLANG_CXX_LIBRARY'] = 'libc++'android/src/main/java/com/usercentrics/reactnative/RNUsercentricsPackage.kt (1)
41-41: Confirm hasConstants flag.Set to true only if the module actually exports constants; otherwise set to false to avoid unnecessary initialization work.
If no constants are exported, flip to false.
android/build.gradle.kts (1)
4-9: Consider extracting BooleanProperty to a shared buildSrc utility.The
BooleanPropertyhelper is well-written, but if it's used across multiple build scripts (or likely to be), extracting it tobuildSrc/src/main/kotlin/...follows Gradle best practices and improves DRY compliance.However, for a single-file usage, this implementation is acceptable. Verify: is this function also used in
ios/Podfileor other build configs?
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (3)
package-lock.jsonis excluded by!**/package-lock.jsonsample/ios/Podfile.lockis excluded by!**/*.locksample/package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (25)
android/build.gradle.kts(4 hunks)android/gradle.properties(1 hunks)android/src/main/java/com/usercentrics/reactnative/RNUsercentricsPackage.kt(1 hunks)android/src/main/jni/CMakeLists.txt(1 hunks)android/src/main/jni/RNUsercentricsModule.cpp(1 hunks)android/src/main/jni/rn_usercentrics.cpp(1 hunks)package.json(3 hunks)react-native.config.js(1 hunks)sample/android/app/build.gradle.kts(0 hunks)sample/android/app/src/main/java/com/usercentrics/reactnativesdk/sample/MainActivity.kt(1 hunks)sample/android/app/src/main/java/com/usercentrics/reactnativesdk/sample/MainApplication.kt(1 hunks)sample/android/gradle.properties(1 hunks)sample/ios/Podfile(2 hunks)sample/ios/sample-Bridging-Header.h(1 hunks)sample/ios/sample.xcodeproj/project.pbxproj(13 hunks)sample/ios/sample/AppDelegate.swift(1 hunks)sample/metro.config.js(0 hunks)sample/package.json(2 hunks)sample/patches/react-native+0.79.6.patch(1 hunks)sample/scripts/fix-react-logger.sh(1 hunks)sample/scripts/test-ios-build.sh(1 hunks)scripts/generate-codegen-jni.js(1 hunks)scripts/publish-local.sh(2 hunks)src/NativeUsercentrics.ts(3 hunks)src/fabric/NativeUsercentricsModule.ts(1 hunks)
💤 Files with no reviewable changes (2)
- sample/metro.config.js
- sample/android/app/build.gradle.kts
🧰 Additional context used
🧬 Code graph analysis (3)
src/NativeUsercentrics.ts (1)
src/fabric/NativeUsercentricsModule.ts (1)
Spec(4-49)
src/fabric/NativeUsercentricsModule.ts (1)
src/NativeUsercentrics.ts (1)
Spec(16-61)
android/src/main/jni/RNUsercentricsModule.cpp (1)
ios/RNUsercentricsModule.swift (1)
moduleName(23-25)
🪛 Clang (14.0.6)
android/src/main/jni/rn_usercentrics.cpp
[error] 1-1: 'jni.h' file not found
(clang-diagnostic-error)
android/src/main/jni/RNUsercentricsModule.cpp
[error] 1-1: 'ReactCommon/JavaTurboModule.h' file not found
(clang-diagnostic-error)
sample/ios/sample-Bridging-Header.h
[error] 5-5: 'React/RCTBridgeModule.h' file not found
(clang-diagnostic-error)
🪛 RuboCop (1.81.1)
sample/ios/Podfile
[convention] 31-31: Avoid comma after the last parameter of a method call.
(Style/TrailingCommaInArguments)
🪛 Shellcheck (0.11.0)
sample/scripts/test-ios-build.sh
[warning] 8-8: Use 'cd ... || exit' or 'cd ... || return' in case cd fails.
(SC2164)
🔇 Additional comments (23)
sample/android/app/src/main/java/com/usercentrics/reactnativesdk/sample/MainApplication.kt (3)
4-13: Imports align with modern RN defaults.Good switch to PackageList, DefaultReactNativeHost/ReactHost, and SoLoader with OpenSourceMergedSoMapping.
40-41: New Architecture entry point load is correctly gated.Matches RN template; no issues.
27-30: BuildConfig flags verified and correct.The fields
IS_NEW_ARCHITECTURE_ENABLEDandIS_HERMES_ENABLEDare properly defined inandroid/build.gradle.kts(lines 31–32) viabuildConfigField(), and the React Native Android dependency is correctly declared. The code changes are approved.sample/patches/react-native+0.79.6.patch (1)
1-24: Review comment is incomplete—patch is only one part of the iOS/Android fixes.The patch file is technically sound, but the review comment overlooks a critical piece: the postinstall script runs both
patch-packageand./scripts/fix-react-logger.sh. The secondary script fixes iOS-specific umbrella header include paths for Xcode 26 compatibility.Clarifications needed:
- Scope mismatch: The patch addresses C compilation strictness (adding
enumqualifier), whilefix-react-logger.shaddresses iOS include path resolution. How does this together resolve "iOS and Android" issues? No Android-specific fix script is visible in postinstall.- Verify both fixes: Confirm that:
- The patch (enum keyword addition) resolves Android C compilation issues
- The fix-react-logger.sh resolves iOS build issues
- Consider upstream reporting: If the enum typing issue exists in React Native 0.79.6, consider reporting it so it's fixed at the source.
- Maintenance risk: Both patch-package and post-install scripts require maintenance when upgrading React Native versions.
sample/ios/sample.xcodeproj/project.pbxproj (3)
13-14: Pods framework linkage looks correct.Pods_sample.framework ref and inclusion in the Frameworks phase are consistent with CocoaPods integration. No action needed.
Also applies to: 18-19, 32-38
188-221: Pods XCFileLists build phases are set up properly.Embed and Resources phases reference configuration‑scoped xcfilelists and scripts; this is the recommended setup. LGTM.
284-285: Bridging header setting is correct and verified.Verification confirms both SWIFT_OBJC_BRIDGING_HEADER occurrences (lines 284 and 316) correctly point to
"$(SRCROOT)/sample-Bridging-Header.h". The filesample/ios/sample-Bridging-Header.hexists at the expected location, and the$(SRCROOT)variable resolves correctly in the build context. Code changes are approved.sample/ios/sample-Bridging-Header.h (1)
5-7: Original review comment is incorrect—imports are valid for RN 0.81.4.The imports
#import <React/RCTBridgeModule.h>,#import <React/RCTViewManager.h>, and#import <React/RCTBridge.h>are correct for React Native 0.81.4. "File not found" errors are not caused by wrong import paths but by missingpod install, using the wrong.xcworkspace, or misconfigured header search paths. The suggested alternative paths (e.g.,React_NativeModulesApple/RCTBridgeModule.h) are not documented as valid import locations in React Native 0.81.4 guidance and should not be used. Keep the bridging header as-is, and fix the build environment instead (ensure pods are installed and open the.xcworkspace).Likely an incorrect or invalid review comment.
sample/android/app/src/main/java/com/usercentrics/reactnativesdk/sample/MainActivity.kt (1)
21-25: Gradle configuration verified; manual file verification needed.The
buildConfigField("boolean", "IS_NEW_ARCHITECTURE_ENABLED", ...)is correctly defined inandroid/build.gradle.kts:31withindefaultConfig, applying to all build variants. The value is dynamically wired viaBooleanProperty("newArchEnabled")andbuildConfig = trueis enabled, ensuring the BuildConfig class is generated.However, I could not locate the MainActivity.kt file at the specified path during automated verification. Please confirm:
- The file exists at the path shown in the code snippet
- No other
DefaultReactActivityDelegateinstantiations have hardcoded boolean values elsewhere in the codebasereact-native.config.js (1)
5-12: Remove review comment; componentDescriptors is supported and correctly configured.The Community React Native CLI accepted a dependency.platforms.android.componentDescriptors entry used for the New Architecture, and your project uses
@react-native-community/cli@^18.0.0, which actively supports this property. Deprecation occurred only in CLI v19.0.0. SincenewArchEnabled=trueis set in gradle.properties, having this config key is appropriate. The empty array is a valid state—it simply means no custom ComponentDescriptors are being registered via CLI config.android/gradle.properties (1)
5-5: ABI list LGTM.All primary ABIs included; good for emulator/device coverage.
sample/package.json (2)
16-18: All helper scripts are properly configured.The verification confirms that all three scripts referenced in
package.jsonexist and have executable permissions (+x). No issues require fixes.
49-51: Based on my verification, the original review comment's concern is unfounded:React 19's TypeScript upgrade only requires updating the types packages, but no minimum TypeScript compiler version is explicitly specified. The web search results from the React upgrade guide contain no mention of a specific TypeScript compiler version requirement.
TypeScript 5.7 (November 2024) and 5.8 (March 2025) are the latest stable versions, meaning TS 5.3.0 (released November 2023) is outdated in terms of feature currency but not compatibility. More importantly, React 19 documentation instructs adding TypeScript as a dev dependency and using a current/stable release—there is no evidence that TS 5.3 is incompatible.
The
~5.3.0constraint is a lock (allowing only 5.3.x patches), not a bug. If flexibility is desired, using^5.3.0would be more idiomatic. However, this is not a critical compatibility issue.
TypeScript version pin does not block compatibility with React 19.1 or React Native 0.81.
The current pin of
~5.3.0will work. If you prefer broader version support to reduce friction during upgrades, consider changing to^5.3.0or^5.6.0(current stable). Otherwise, no action is required.Likely an incorrect or invalid review comment.
src/NativeUsercentrics.ts (1)
63-65: Type-cast pattern is sound with runtime safeguard in place.The code's fallback approach is type-safe:
Speccorrectly extendsTurboModule,TurboModuleRegistry.get<Spec>()is properly typed, and the||fallback toNativeModules.RNUsercentricsModule(typed asany) is acceptable since the runtime check at line 66 (if (!RNUsercentricsModule)) ensures the module is defined before export. Theas Speccast is justified here.For clarity, consider using a type annotation on the const instead:
const RNUsercentricsModule: Spec = ..., which makes the intent explicit without relying on the export-level cast.android/src/main/jni/rn_usercentrics.cpp (1)
13-18: Code structure is correct; verify NDK build succeeds locally.The JNI_OnLoad signature, fbjni initialization pattern, and includes are all correct. The "jni.h not found" static analysis warning is expected outside an NDK build context. However, actual compilation must be verified with a local NDK build since the sandbox cannot execute gradle commands.
src/fabric/NativeUsercentricsModule.ts (1)
4-49: Do not follow the suggested refactor—React Native 0.79 Codegen requires types to be defined inline.RN 0.79 Codegen expects TurboModule spec types/shapes to be declared in the spec file and does not reliably resolve imported/sibling TypeScript types. The suggested import-based refactor would break the native module codegen.
While type alignment between
Specandsrc/NativeUsercentrics.tsis worth noting, the solution is not to import types into the spec. Instead:
- Keep the Spec types inline (as required by codegen)
- Document the intentional separation and type mapping in comments or a shared types guide
- Maintain manual synchronization if both files must evolve
Likely an incorrect or invalid review comment.
package.json (1)
63-65: Version pairing and codegenConfig are officially compatible—no action required.React 19 is officially supported by React Native 0.79.x, confirming your react@^19.1.0 and react-native@^0.79.6 pairing is compatible. The codegenConfig schema for RN 0.79 includes the fields type and jsSrcsDir, so your configuration is correct.
android/src/main/jni/CMakeLists.txt (1)
18-26: The review comment is incorrect and should be dismissed.The review assumes both
CMakeLists.txtfiles would be included in the same build, causing a duplicate target conflict. However, verification reveals:
- The generated
CMakeLists.txtis created inandroid/build/generated/source/codegen/jni/(build directory), which is explicitly excluded from npm packages viapackage.json's"!build"directive and.gitignore- The Android Gradle build has no CMake configuration (
externalNativeBuildis absent), so neither CMakeLists file is actually invoked during the build- Only the source
android/src/main/jni/CMakeLists.txtis included in published packages- The two files never coexist in the same context where CMake would load both
The build and packaging configuration prevents the alleged conflict from occurring.
Likely an incorrect or invalid review comment.
android/src/main/jni/RNUsercentricsModule.cpp (1)
12-15: The review comment is incorrect. The C++ provider returning nullptr is the correct design.This module is implemented in Java/Kotlin and is registered via
RNUsercentricsPackage(which extendsTurboReactPackage). React Native uses two separate module loading paths: a C++ provider path for pure C++ modules, and a Java package path for Java/Kotlin modules. TheRNUsercentricsModule_ModuleProviderC++ function is never invoked because the module is loaded via the Java path throughTurboReactPackage.getModule(). Returningnullptrfrom the unused C++ provider is intentional and correct—it signals that the module is not available through the C++ path. The proposed change to returnJavaTurboModulewould create dead code that is never called.Likely an incorrect or invalid review comment.
scripts/generate-codegen-jni.js (1)
55-89: Guard generated CMake target to prevent redefinition and modernize dependencies.The target name
react_codegen_RNUsercentricsModulecollides withandroid/src/main/jni/CMakeLists.txtline 5. Whiletarget_link_librarieson OBJECT libraries is valid in CMake 3.13+, add a guard to prevent duplicate target errors if both CMakeLists.txt files are included. Also consider using modern imported targets (ReactAndroid::, fbjni::) for consistency with your existing build configuration.Apply this diff:
-const cmakeFile = `# Minimal CMake stub for RNUsercentricsModule +const cmakeFile = `# Minimal CMake stub for RNUsercentricsModule cmake_minimum_required(VERSION 3.13) set(CMAKE_VERBOSE_MAKEFILE ON) file(GLOB react_codegen_SRCS CONFIGURE_DEPENDS *.cpp) -add_library( - react_codegen_RNUsercentricsModule - OBJECT - \${react_codegen_SRCS} -) +if(NOT TARGET react_codegen_RNUsercentricsModule) + add_library( + react_codegen_RNUsercentricsModule + OBJECT + \${react_codegen_SRCS} + ) -target_include_directories( - react_codegen_RNUsercentricsModule - PUBLIC - . -) + target_include_directories( + react_codegen_RNUsercentricsModule + PUBLIC + . + ) -target_link_libraries( - react_codegen_RNUsercentricsModule - fbjni - jsi - reactnative -) + # Use modern imported targets when available (RN 0.76+) + if(ReactAndroid_VERSION_MINOR GREATER_EQUAL 76) + target_link_libraries( + react_codegen_RNUsercentricsModule + ReactAndroid::reactnative + ReactAndroid::jsi + fbjni::fbjni + ) + else() + target_link_libraries( + react_codegen_RNUsercentricsModule + fbjni + jsi + reactnative + ) + endif() -target_compile_options( - react_codegen_RNUsercentricsModule - PRIVATE - -DLOG_TAG=\\"ReactNative\\" - -fexceptions - -frtti - -std=c++20 - -Wall -) + target_compile_options( + react_codegen_RNUsercentricsModule + PRIVATE + -DLOG_TAG=\\"ReactNative\\" + -fexceptions + -frtti + -std=c++20 + -Wall + ) +endif() `;android/build.gradle.kts (3)
13-13: Verify React plugin is only applied when new architecture is enabled.The conditional application of the React plugin is a good pattern for architecture flexibility. Ensure:
- The React Native plugin does not introduce side effects during parsing (even when not applied).
- Downstream code safely handles the absence of plugin tasks when
isNewArchitectureEnabled = false.Also applies to: 16-18
31-32: BuildConfig flags look correct.The use of
.toString()to convert Kotlin Boolean to String is appropriate forbuildConfigField. Verify that Java/Kotlin code consumingBuildConfig.IS_NEW_ARCHITECTURE_ENABLEDandBuildConfig.IS_HERMES_ENABLEDaligns with the flag definitions.
72-83: Test dependencies structure is clean.The clear separation of unit tests and instrumented tests is good practice. Versions and scopes align with expected patterns.
| val usercentricsVersion = "2.23.3" | ||
| val reactNativeVersion = "+" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
Pin React Native version for reproducible builds and library stability.
Using "+" as a version specifier allows any version, which violates reproducible-build principles and can introduce breaking changes. This is especially critical for a library: consumers need stable, predictable transitive dependencies.
Apply this diff to pin a specific version:
-val reactNativeVersion = "+"
+val reactNativeVersion = "0.73.0" // or an appropriate stable versionIf you need flexibility across multiple versions, document the supported range in README.md and use a bounded range (e.g., 0.73.+ or explicit range), or manage it via build.gradle instead of hardcoding here.
Please verify the intended React Native version(s) to support and confirm this is not a temporary placeholder.
I need to gather information to properly verify this review comment. Let me inspect the actual codebase and search for best practices.
🏁 Script executed:
#!/bin/bash
# Inspect the actual android/build.gradle.kts file to see full context
if [ -f "android/build.gradle.kts" ]; then
echo "=== android/build.gradle.kts (first 100 lines) ==="
head -100 android/build.gradle.kts
echo -e "\n=== Total lines in file ==="
wc -l android/build.gradle.kts
else
echo "File not found at android/build.gradle.kts"
# Try to find it
find . -name "build.gradle.kts" -type f | head -20
fiLength of output: 2429
🌐 Web query:
Gradle "+" version specifier React Native dependencies best practices
💡 Result:
Short answer: avoid using the "+" (dynamic) version specifier for React Native Android dependencies in production. It can resolve to a newer incompatible artifact at build time, cause non-reproducible builds, and break RN native linking. Instead pin versions and use Gradle features to make upgrades deliberate and reproducible. [1][2][3][4]
Practical best practices
- Don’t use "+" in app libs (e.g. change implementation "com.facebook.react:react-native:+" → implementation "com.facebook.react:react-native:0.71.8" or whatever exact RN version you ship). This prevents Gradle from pulling a higher incompatible RN artifact from Maven. [3][4]
- Centralize versions (Version Catalogs / gradle.properties) so you update one place. [1]
- Use dependency locking or Gradle lockfiles to guarantee reproducible builds across machines/CI. [1][2]
- If you must allow some flexibility, prefer explicit ranges or the newer Gradle features (strictly/require/feature variants) and combine with resolutionStrategy rules to control unexpectedly chosen versions. Don’t rely on “+”. [1][2][3]
- For React Native projects specifically: prefer the React Native Gradle Plugin (it manages native artifact versions) or explicitly force com.facebook.react to your project’s RN version with resolutionStrategy when integrating into existing apps. That avoids the classpath mismatch issues seen when "+" resolves to an unintended RN version. [4][5]
Quick examples
- Pin version:
implementation "com.facebook.react:react-native:0.71.8". [4] - Force resolution (example in root build.gradle):
configurations.all {
resolutionStrategy.force("com.facebook.react:react-native:0.71.8")
}
(Use only if you understand side effects.) [3][4] - Enable dependency locking:
./gradlew dependencies --write-locks (see Gradle docs). [1]
If you want, tell me your React Native version and Gradle/AGP versions and I’ll propose an exact migration/lock strategy and a short patch you can apply.
I found the issue is real and valid. Let me check for context on what the intended React Native version should be:
🏁 Script executed:
#!/bin/bash
# Look for React Native version hints in project files
echo "=== Looking for version information ==="
echo
echo "--- README.md ---"
if [ -f "README.md" ]; then
grep -i "react\|version" README.md | head -10
else
echo "No README.md found"
fi
echo
echo "--- package.json (if exists) ---"
if [ -f "package.json" ]; then
cat package.json | head -30
fi
echo
echo "--- gradle.properties ---"
if [ -f "gradle.properties" ]; then
cat gradle.properties
fi
echo
echo "--- Other build.gradle files ---"
find . -name "build.gradle" -o -name "build.gradle.kts" | grep -v ".gradle/" | xargs ls -la 2>/dev/null
echo
echo "--- Git history for this line (if available) ---"
git log -p --follow -S 'reactNativeVersion = "+"' -- android/build.gradle.kts 2>/dev/null | head -50 || echo "Git history not available"Length of output: 756
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| val usercentricsVersion = "2.23.3" | |
| val reactNativeVersion = "+" | |
| val usercentricsVersion = "2.23.3" | |
| val reactNativeVersion = "0.78.3" |
🤖 Prompt for AI Agents
In android/build.gradle.kts around lines 1 to 2, the React Native version is set
to "+" which causes non-reproducible builds and forces consumers to work around
dependency resolution; replace the "+" with a pinned React Native version (e.g.,
"0.78.3") or a bounded range like "0.78.+" to ensure stable, reproducible
dependency resolution, and update README to document supported React Native
versions if you plan to support multiple releases.
| getByName("main").java.srcDirs( | ||
| "src/main/kotlin", | ||
| "$buildDir/generated/codegen/NativeModules" | ||
| ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
Verify generated codegen path exists or is created before build.
Adding "$buildDir/generated/codegen/NativeModules" to srcDirs assumes this directory exists or is created during the build. If codegen is not run or fails, the build may break unexpectedly.
Confirm:
- Is there a codegen task that guarantees this directory is created before compilation?
- Does the build fail gracefully if the path is missing?
- Should this path be added conditionally (only when
isNewArchitectureEnabled = true)?
🏁 Script executed:
#!/bin/bash
# Search for codegen task or configuration that generates this directory
rg -i "codegen|NativeModules" --type=gradle --type=kts -A 3 -B 3Length of output: 27
🏁 Script executed:
#!/bin/bash
# Search for codegen or NativeModules references in gradle files
rg -i "codegen|NativeModules" -A 3 -B 3 --type gradleLength of output: 1164
🏁 Script executed:
#!/bin/bash
# Search all .gradle and .kts files for codegen/task definitions
fd -e gradle -e kts | head -20 | xargs rg -i "codegen|NativeModules|register.*Task" -A 2 -B 2Length of output: 1784
🏁 Script executed:
#!/bin/bash
# Look for sourceSet configurations and task dependencies
rg "sourceSets\|tasks\s*{" --type gradle -A 5 -B 2Length of output: 105
🏁 Script executed:
#!/bin/bash
# Check for isNewArchitectureEnabled conditions
rg "isNewArchitectureEnabled" -A 5 -B 2Length of output: 1249
🏁 Script executed:
#!/bin/bash
# Get full context around lines 50-53 in android/build.gradle.kts
cat android/build.gradle.kts | head -80 | tail -40Length of output: 1061
🏁 Script executed:
#!/bin/bash
# Look for all sourceSets and tasks blocks in the file
rg -n "sourceSets|tasks|if.*isNewArchitectureEnabled" android/build.gradle.kts -B 1 -A 8Length of output: 446
🏁 Script executed:
#!/bin/bash
# Check the com.facebook.react plugin behavior - search in node_modules or docs
find . -name "*facebook*react*" -type f 2>/dev/null | head -10Length of output: 0
🌐 Web query:
React Native Codegen Android gradle generated NativeModules directory
💡 Result:
The Codegen-generated Android files (including NativeModules/Turbo module Java/Kotlin and JNI glue) are written to your Gradle build's generated folder:
- For the app: android/app/build/generated/source/codegen (java and jni subfolders).
- For a dependency module: node_modules//android/build/generated/source/codegen.
To produce them run the Gradle task from the android directory:
- ./gradlew generateCodegenArtifactsFromSchema
Or use the Codegen CLI:
- npx @react-native-community/cli codegen --platform android (you can pass --outputPath to change the output).
Docs: React Native — Using Codegen (generated path + gradle task) and Codegen CLI. [1][2][3]
Sources
[1] React Native — Using Codegen (Android generated path & gradle task).
[2] React Native — Codegen CLI (npx @react-native-community/cli codegen).
[3] React Native — New-architecture / library Android (generator writes to ./build/generated/source/codegen).
Fix incorrect codegen path and conditional sourceSets configuration.
The generated codegen path and sourceSets configuration have two issues:
-
Incorrect path structure: React Native Codegen generates files to
build/generated/source/codegenfor dependency modules, but the code references$buildDir/generated/codegen/NativeModules(wrong subdirectory structure). -
Conditional mismatch: The sourceSets block (lines 50-53) is added unconditionally to the
androidblock, but thecom.facebook.reactplugin that enables codegen is applied only whenisNewArchitectureEnabled = true(lines 16-18). This causes build failures when the new architecture is disabled—the sourceSets points to a path that will never be generated.
Fix: Move the sourceSets block inside the if (isNewArchitectureEnabled) conditional block, and use the correct path structure: build/generated/source/codegen.
🤖 Prompt for AI Agents
In android/build.gradle.kts around lines 50 to 53, the sourceSets entry uses the
wrong generated-code path and is added unconditionally; move that
getByName("main").java.srcDirs(...) call inside the existing if
(isNewArchitectureEnabled) block (the same place where the com.facebook.react
codegen plugin is applied around lines ~16-18) and change the path to the
correct generated folder (use "$buildDir/generated/source/codegen" instead of
"$buildDir/generated/codegen/NativeModules") so the source set is only
configured when codegen runs and points to the proper directory.
| ReactModuleInfo( | ||
| RNUsercentricsModule.NAME, | ||
| RNUsercentricsModule.NAME, | ||
| false, // canOverrideExistingModule | ||
| false, // needsEagerInit | ||
| true, // hasConstants | ||
| false, // isCxxModule | ||
| isTurboModule, | ||
| ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix className in ReactModuleInfo.
Second parameter must be the fully qualified class name, not the module name. Using the name twice can break legacy reflection paths.
Apply:
- ReactModuleInfo(
- RNUsercentricsModule.NAME,
- RNUsercentricsModule.NAME,
+ ReactModuleInfo(
+ RNUsercentricsModule.NAME,
+ RNUsercentricsModule::class.java.name,
false, // canOverrideExistingModule
false, // needsEagerInit
true, // hasConstants
false, // isCxxModule
isTurboModule,
)🤖 Prompt for AI Agents
In android/src/main/java/com/usercentrics/reactnative/RNUsercentricsPackage.kt
around lines 36 to 44, the ReactModuleInfo is passing the module NAME as both
parameters but the second parameter must be the fully qualified class name;
replace the second argument with the module's fully qualified class name (e.g.,
RNUsercentricsModule::class.java.name or the explicit package-qualified class
name string) so legacy reflection paths receive the correct class identifier.
| target_include_directories( | ||
| ${CMAKE_PROJECT_NAME} | ||
| PUBLIC | ||
| ${CMAKE_CURRENT_SOURCE_DIR} | ||
| ) No newline at end of file |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix incorrect target in target_include_directories.
You’re setting include dirs on ${CMAKE_PROJECT_NAME}, which is not your library target and often isn’t a CMake target at all. Use ${LIB_TARGET_NAME}.
Apply this diff:
-target_include_directories(
- ${CMAKE_PROJECT_NAME}
- PUBLIC
- ${CMAKE_CURRENT_SOURCE_DIR}
-)
+target_include_directories(
+ ${LIB_TARGET_NAME}
+ PUBLIC
+ ${CMAKE_CURRENT_SOURCE_DIR}
+)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| target_include_directories( | |
| ${CMAKE_PROJECT_NAME} | |
| PUBLIC | |
| ${CMAKE_CURRENT_SOURCE_DIR} | |
| ) | |
| target_include_directories( | |
| ${LIB_TARGET_NAME} | |
| PUBLIC | |
| ${CMAKE_CURRENT_SOURCE_DIR} | |
| ) |
🤖 Prompt for AI Agents
In android/src/main/jni/CMakeLists.txt around lines 81 to 85, the
target_include_directories call is incorrectly using ${CMAKE_PROJECT_NAME}
(which is not the library target); change the target argument to
${LIB_TARGET_NAME} so the include directory is applied to the actual library
target (keep the PUBLIC scope and ${CMAKE_CURRENT_SOURCE_DIR} as the include
path).
| # =========================== | ||
| # Enable the New Architecture (Fabric / TurboModules) | ||
| newArchEnabled=false | ||
| newArchEnabled=true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
Verify new architecture wiring end-to-end.
With newArchEnabled=true, ensure:
- Android build defines BuildConfig.IS_NEW_ARCHITECTURE_ENABLED accordingly in the library.
- Codegen artifacts (TurboModule stubs) are generated before assemble.
You can grep for NAME/ModuleProvider:
🏁 Script executed:
#!/bin/bash
rg -nP 'const\\s+val\\s+NAME|object\\s+RNUsercentricsModule|class\\s+RNUsercentricsModule'
rg -n 'generated|ModuleProvider|RNUsercentricsModule\\.h|\\.cpp' android/ src/ scripts/Length of output: 1162
---
🏁 Script executed:
```shell
#!/bin/bash
# Check gradle build configuration for BuildConfig and newArchEnabled usage
rg -nP 'BuildConfig\.IS_NEW_ARCHITECTURE_ENABLED|newArchEnabled' android/
# Check if generate-codegen-jni.js is invoked in gradle tasks
rg -nP 'generate-codegen-jni|generateCodegenJni|codegen.*task' android/build.gradle.kts
# Check for TurboModule registration/provider in the native code
rg -nP 'getPackages|getTurboModules|react::TurboModule|ModuleProvider' android/src/main/jni/ android/src/main/cpp/ 2>/dev/null || true
Length of output: 356
🏁 Script executed:
#!/bin/bash
# Verify the structure of gradle.properties to understand newArchEnabled scope
head -20 sample/android/gradle.properties || head -20 android/gradle.properties 2>/dev/null || echo "gradle.properties not found in sample/android"Length of output: 537
---
🏁 Script executed:
```shell
#!/bin/bash
# Check how BuildConfig.IS_NEW_ARCHITECTURE_ENABLED is generated from gradle
rg -nP 'buildConfigField.*IS_NEW_ARCHITECTURE_ENABLED|BooleanProperty.*newArchEnabled' android/build.gradle.kts
# Check gradle task dependencies and when generate-codegen-jni.js task runs
rg -nP 'tasks\.|preBuild|generateCodegen|\.dependsOn|generate-codegen-jni' android/build.gradle.kts
# Check RNUsercentricsPackage initialization and TurboModule usage context
rg -nA5 'isTurboModule.*BuildConfig\.IS_NEW_ARCHITECTURE_ENABLED' android/src/main/java/com/usercentrics/reactnative/RNUsercentricsPackage.kt
Length of output: 499
🏁 Script executed:
#!/bin/bash
# Extract the full context around BooleanProperty newArchEnabled in build.gradle.kts
head -30 android/build.gradle.kts 2>/dev/null || echo "build.gradle.kts preview unavailable"Length of output: 751
---
🏁 Script executed:
```shell
#!/bin/bash
# Check if generate-codegen-jni.js is registered as a gradle task and its execution order
rg -nP 'register|task.*generate|exec.*generate-codegen-jni|preBuild.*generate' android/build.gradle.kts
# Look for packageJson scripts that might invoke codegen
cat package.json 2>/dev/null | grep -A20 '"scripts"' || echo "package.json scripts section"
# Check if there's a prebuild hook or prepare script
rg -n 'generate-codegen-jni' package.json scripts/ 2>/dev/null || true
Length of output: 1103
🏁 Script executed:
#!/bin/bash
# Look for any gradle task that might invoke the JS codegen script
rg -nP 'node.*generate-codegen-jni|exec.*generate-codegen-jni' . --type=gradle --type=json 2>/dev/null || true
# Check if there's a doFirst or doLast hook in build tasks
rg -nA3 'doFirst\s*\{|doLast\s*\{' android/build.gradle.kts | head -40Length of output: 166
---
🏁 Script executed:
```shell
#!/bin/bash
# Final check: confirm no gradle hooks execute node or shell scripts in build pipeline
rg -nP 'exec\s*\(|exec\s*\{|ProcessGroovyMethods|Runtime\.getRuntime|\.sh|node\s' android/build.gradle.kts
# Check for any gradle extensions or plugins that might handle codegen
rg -nP 'plugins|apply\s+plugin' android/build.gradle.kts
Length of output: 12
Integrate codegen generation into gradle build pipeline before native compilation.
The new architecture is properly wired (BuildConfig flag, TurboModule registration, C++ provider), but generate-codegen-jni.js only runs during npm publish and npm pack—not during gradle builds. Local development and CI/CD gradle builds will fail due to missing RNUsercentricsModule-generated.cpp.
Add a gradle task in android/build.gradle.kts that executes node scripts/generate-codegen-jni.js as a dependency of the preBuild or assemble task to ensure codegen stubs are generated before native compilation.
🤖 Prompt for AI Agents
In sample/android/gradle.properties around line 12, newArchEnabled=true is set
but codegen generation (scripts/generate-codegen-jni.js) only runs on npm
publish/pack and not during Gradle builds, so native builds fail due to missing
RNUsercentricsModule-generated.cpp; update android/build.gradle.kts to add a
Gradle task that runs the Node script (node scripts/generate-codegen-jni.js) and
make it a dependency of preBuild (or assemble) so the codegen script executes
before native compilation, ensuring generated JNI/C++ stubs exist for the new
architecture.
| #!/bin/bash | ||
|
|
||
| # Script to fix React-logger compatibility issues with Xcode 26 | ||
| # This script should be executed after each 'pod install' | ||
|
|
||
| echo "🔧 Applying React-logger fixes for Xcode 26..." | ||
|
|
||
| # Path to React-logger-umbrella.h file | ||
| UMBRELLA_FILE="ios/Pods/Target Support Files/React-logger/React-logger-umbrella.h" | ||
|
|
||
| if [ -f "$UMBRELLA_FILE" ]; then | ||
| echo "📝 Fixing includes in React-logger-umbrella.h..." | ||
|
|
||
| # Fix include from double quotes to angle brackets | ||
| sed -i '' 's|#import "react_native_log.h"|#import <React-logger/react_native_log.h>|g' "$UMBRELLA_FILE" | ||
|
|
||
| echo "✅ React-logger-umbrella.h fixed!" | ||
| else | ||
| echo "⚠️ React-logger-umbrella.h file not found. Run 'pod install' first." | ||
| fi | ||
|
|
||
| echo "🎉 React-logger fixes applied successfully!" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make the fix portable and correct the Xcode version note.
Current sed command is macOS-specific and script always runs on postinstall. Gate to macOS and use portable in-place edit. Also, “Xcode 26” looks like a typo.
Apply:
-#!/bin/bash
+#!/bin/bash
+set -u
@@
-# Script to fix React-logger compatibility issues with Xcode 26
+# Script to fix React-logger compatibility issues with Xcode 16+ (header include path)
@@
-echo "🔧 Applying React-logger fixes for Xcode 26..."
+echo "🔧 Applying React-logger fixes for Xcode (macOS only)..."
+
+# Run only on macOS; no-op on Linux/Windows/CI.
+if [[ "$(uname -s)" != "Darwin" ]]; then
+ echo "ℹ️ Skipping: non-macOS environment."
+ exit 0
+fi
@@
- # Fix include from double quotes to angle brackets
- sed -i '' 's|#import "react_native_log.h"|#import <React-logger/react_native_log.h>|g' "$UMBRELLA_FILE"
+ # Fix include from double quotes to angle brackets (BSD sed)
+ sed -i '' 's|#import "react_native_log.h"|#import <React-logger/react_native_log.h>|g' "$UMBRELLA_FILE" || {
+ echo "⚠️ sed patch failed; please adjust manually."
+ }
@@
- echo "⚠️ React-logger-umbrella.h file not found. Run 'pod install' first."
+ echo "ℹ️ React-logger-umbrella.h not found. Run 'pod install' first (this is expected before pods)."Optional: move this fix to ios/Podfile post_install hook for deterministic iOS-only execution.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| #!/bin/bash | |
| # Script to fix React-logger compatibility issues with Xcode 26 | |
| # This script should be executed after each 'pod install' | |
| echo "🔧 Applying React-logger fixes for Xcode 26..." | |
| # Path to React-logger-umbrella.h file | |
| UMBRELLA_FILE="ios/Pods/Target Support Files/React-logger/React-logger-umbrella.h" | |
| if [ -f "$UMBRELLA_FILE" ]; then | |
| echo "📝 Fixing includes in React-logger-umbrella.h..." | |
| # Fix include from double quotes to angle brackets | |
| sed -i '' 's|#import "react_native_log.h"|#import <React-logger/react_native_log.h>|g' "$UMBRELLA_FILE" | |
| echo "✅ React-logger-umbrella.h fixed!" | |
| else | |
| echo "⚠️ React-logger-umbrella.h file not found. Run 'pod install' first." | |
| fi | |
| echo "🎉 React-logger fixes applied successfully!" | |
| #!/bin/bash | |
| set -u | |
| # Script to fix React-logger compatibility issues with Xcode 16+ (header include path) | |
| # This script should be executed after each 'pod install' | |
| echo "🔧 Applying React-logger fixes for Xcode (macOS only)..." | |
| # Run only on macOS; no-op on Linux/Windows/CI. | |
| if [[ "$(uname -s)" != "Darwin" ]]; then | |
| echo "ℹ️ Skipping: non-macOS environment." | |
| exit 0 | |
| fi | |
| # Path to React-logger-umbrella.h file | |
| UMBRELLA_FILE="ios/Pods/Target Support Files/React-logger/React-logger-umbrella.h" | |
| if [ -f "$UMBRELLA_FILE" ]; then | |
| echo "📝 Fixing includes in React-logger-umbrella.h..." | |
| # Fix include from double quotes to angle brackets (BSD sed) | |
| sed -i '' 's|#import "react_native_log.h"|#import <React-logger/react_native_log.h>|g' "$UMBRELLA_FILE" || { | |
| echo "⚠️ sed patch failed; please adjust manually." | |
| } | |
| echo "✅ React-logger-umbrella.h fixed!" | |
| else | |
| echo "ℹ️ React-logger-umbrella.h not found. Run 'pod install' first (this is expected before pods)." | |
| fi | |
| echo "🎉 React-logger fixes applied successfully!" |
🤖 Prompt for AI Agents
In sample/scripts/fix-react-logger.sh lines 1-22: the script uses a macOS-only
sed invocation and always prints "Xcode 26" (likely a typo); update it to run
only on macOS (guard with uname -s == "Darwin") and make the in-place edit
portable by branching: use sed -i '' on Darwin and sed -i on other platforms (or
use a temporary file + mv for true POSIX portability), correct the Xcode version
note by replacing "Xcode 26" with the intended version (or a neutral phrase like
"Xcode" if unsure), and optionally document/move this fix into the ios/Podfile
post_install hook for deterministic iOS-only execution.
| echo "🧪 Testing iOS compilation with React-logger fixes..." | ||
|
|
||
| # Navigate to iOS directory | ||
| cd ios |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add error handling for the cd command to prevent executing subsequent commands in the wrong directory.
If the cd command fails, the subsequent destructive operations (like rm -rf on line 17) could execute in an unintended directory and corrupt the repository or user's system.
Apply this diff to add error handling:
-cd ios
+cd ios || exit 1This follows the shellcheck recommendation (SC2164) and ensures the script exits immediately if navigation fails.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| cd ios | |
| cd ios || exit 1 |
🧰 Tools
🪛 Shellcheck (0.11.0)
[warning] 8-8: Use 'cd ... || exit' or 'cd ... || return' in case cd fails.
(SC2164)
🤖 Prompt for AI Agents
In sample/scripts/test-ios-build.sh around line 8, the bare "cd ios" can fail
and allow subsequent destructive commands to run in the wrong directory; update
the script so that after attempting to change directory you test the result and
immediately exit with a non‑zero status (and an explanatory error message) if
the cd fails, preventing further commands from executing in the wrong location.
| echo "🧹 Cleaning CocoaPods cache..." | ||
| pod cache clean --all | ||
| rm -rf ~/Library/Caches/CocoaPods |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reconsider the risky rm -rf ~/Library/Caches/CocoaPods command in a test script.
Running rm -rf on a user's cache directory can have unintended side effects on the developer's system. Consider alternatives such as:
- Using CocoaPods cache cleanup flags instead (e.g.,
pod repo updateorpod deintegrate). - Making the cache cleanup optional via a flag.
- Documenting that this operation will clear the user's CocoaPods cache.
If cache cleanup is necessary for the test, consider a safer approach:
-# Clean CocoaPods cache to avoid build_configurations errors
-echo "🧹 Cleaning CocoaPods cache..."
-pod cache clean --all
-rm -rf ~/Library/Caches/CocoaPods
+# Clean CocoaPods cache to avoid build_configurations errors
+echo "🧹 Cleaning CocoaPods cache..."
+pod cache clean --all
+# Optionally clean local pod cache: rm -rf Pods && rm -rf Podfile.lockCommittable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In sample/scripts/test-ios-build.sh around lines 15 to 17, the script uses a
risky unconditional rm -rf ~/Library/Caches/CocoaPods which can wipe a
developer's cache; replace this with a safer approach: use CocoaPods commands
(e.g., pod cache clean --all, pod repo update, or pod deintegrate) to clear only
CocoaPods artifacts, or make the destructive cache removal optional behind a
--force or --clean-cache flag with an explicit confirmation prompt and
documentation in the script header README noting that running with that flag
will clear the user's CocoaPods cache.
| # Find available iOS simulator | ||
| echo "🔍 Finding available iOS simulator..." | ||
| SIMULATOR=$(xcrun simctl list devices | grep "iPhone" | head -1 | grep -o '([A-F0-9-]*)' | tr -d '()') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Improve the fragility of the iOS simulator detection logic.
The regex-based extraction of the simulator ID (line 25) may fail across different Xcode versions or simulator output formats. A more robust approach is to use xcrun simctl directly.
Apply this diff to use a more robust simulator detection method:
-# Find available iOS simulator
-echo "🔍 Finding available iOS simulator..."
-SIMULATOR=$(xcrun simctl list devices | grep "iPhone" | head -1 | grep -o '([A-F0-9-]*)' | tr -d '()')
+# Find available iOS simulator
+echo "🔍 Finding available iOS simulator..."
+SIMULATOR=$(xcrun simctl list devices available --json | python3 -c "import json,sys; devices = json.load(sys.stdin); uuids = [d.get('udid') for r in devices.get('devices', {}).values() for d in r if 'iPhone' in d.get('name', '')]; print(uuids[0] if uuids else '')")This uses JSON parsing to reliably extract a simulator UUID regardless of output format variations.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| # Find available iOS simulator | |
| echo "🔍 Finding available iOS simulator..." | |
| SIMULATOR=$(xcrun simctl list devices | grep "iPhone" | head -1 | grep -o '([A-F0-9-]*)' | tr -d '()') | |
| # Find available iOS simulator | |
| echo "🔍 Finding available iOS simulator..." | |
| SIMULATOR=$(xcrun simctl list devices available --json | python3 -c "import json,sys; devices = json.load(sys.stdin); uuids = [d.get('udid') for r in devices.get('devices', {}).values() for d in r if 'iPhone' in d.get('name', '')]; print(uuids[0] if uuids else '')") |
🤖 Prompt for AI Agents
In sample/scripts/test-ios-build.sh around lines 23 to 25, replace the fragile
grep/regex extraction with a JSON-based approach: call xcrun simctl list devices
--json and parse the output with jq to select the first device whose name
contains "iPhone" (prefer state "Booted", otherwise any state) and extract its
udid into SIMULATOR; ensure you handle the case where no simulator is found
(exit with an error message) and document/verify jq is available before parsing.
| @@ -1,4 +1,4 @@ | |||
| import { NativeModules } from 'react-native'; | |||
| import { NativeModules, TurboModuleRegistry, TurboModule } from 'react-native'; | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Import TurboModule as a type to avoid runtime import.
Importing TurboModule as a value can cause bundlers to emit a require for a non-existent export.
Apply this diff:
-import { NativeModules, TurboModuleRegistry, TurboModule } from 'react-native';
+import { NativeModules, TurboModuleRegistry } from 'react-native';
+import type { TurboModule } from 'react-native';📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| import { NativeModules, TurboModuleRegistry, TurboModule } from 'react-native'; | |
| import { NativeModules, TurboModuleRegistry } from 'react-native'; | |
| import type { TurboModule } from 'react-native'; |
🤖 Prompt for AI Agents
In src/NativeUsercentrics.ts around line 1, the current import pulls TurboModule
as a runtime value which can cause bundlers to emit a require for a non-existent
export; change the import to use a type-only import for TurboModule (e.g., use
"import type { TurboModule } from 'react-native'") while keeping other imports
(NativeModules, TurboModuleRegistry) as value imports so TurboModule is erased
at runtime and only used for typing.
30554df to
100906b
Compare
# Conflicts: # sample/ios/Podfile # sample/ios/sample.xcodeproj/project.pbxproj
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (2)
sample/ios/Podfile (2)
1-1: Use English for code comments.The comment contains Portuguese text ("com node para"), which reduces readability for international contributors. Technical comments should be in English for consistency.
Apply this diff:
-# Resolve react_native_pods.rb com node para allow hoisting +# Resolve react_native_pods.rb with node to allow hoisting
8-16: Good centralized configuration, but use English consistently.The centralized NEW_ARCH flag provides clear control over the architecture mode. However, lines 12 and 15 contain Portuguese text ("ou" = "or").
Apply this diff for language consistency:
# Change this value to control New Architecture: # true = Enable New Architecture (TurboModules + Fabric) # false = Use Legacy Architecture # ======================================== -$RCT_NEW_ARCH_ENABLED = false # ← CHANGE HERE: true ou false +$RCT_NEW_ARCH_ENABLED = false # ← CHANGE HERE: true or false
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (2)
sample/ios/Podfile.lockis excluded by!**/*.locksample/package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (7)
sample/ios/Podfile(2 hunks)sample/ios/sample.xcodeproj/project.pbxproj(13 hunks)sample/ios/sample/AppDelegate.swift(1 hunks)sample/ios/sample/Info.plist(0 hunks)sample/ios/sample/PrivacyInfo.xcprivacy(1 hunks)sample/metro.config.js(0 hunks)sample/package.json(2 hunks)
💤 Files with no reviewable changes (2)
- sample/ios/sample/Info.plist
- sample/metro.config.js
🚧 Files skipped from review as they are similar to previous changes (2)
- sample/ios/sample.xcodeproj/project.pbxproj
- sample/ios/sample/AppDelegate.swift
🧰 Additional context used
🪛 RuboCop (1.81.1)
sample/ios/Podfile
[convention] 6-6: Put a comma after the last item of a multiline array.
(Style/TrailingCommaInArrayLiteral)
[convention] 31-31: Avoid comma after the last parameter of a method call.
(Style/TrailingCommaInArguments)
🔇 Additional comments (7)
sample/package.json (4)
50-50: Clarify TypeScript version downgrade.TypeScript was downgraded from
^5.8.3(5.8.3 through <6.0.0) to~5.3.0(5.3.x only). This is a significant backward step that locks to an older patch version, which typically indicates a compatibility constraint rather than a bug fix.Please verify:
- Is this downgrade intentional due to TurboModules codegen tooling compatibility?
- Does TypeScript 5.3.0 have known issues that 5.8.3 resolves?
- Can we use a newer TypeScript version with proper codegen configuration?
If this is a hard requirement for codegen, add a comment in the file explaining the reason. If not, consider upgrading to
~5.8.3or a more recent stable version.
26-26: Verify intentional pinning of react-native version.
react-nativechanged from^0.79.6(allows ≥0.79.6 and <1.0.0) to hardcoded0.81.4. This is significantly more restrictive and suggests an intentional lock for TurboModules/New Architecture compatibility.Confirm:
- Is
0.81.4the minimum required version for TurboModules support?- Should this be
^0.81.4to allow patch/minor updates, or is exact pinning necessary?- Are there known issues with
0.81.5+that necessitate exact pinning?If exact pinning is required, consider adding a comment explaining the constraint.
16-18: Verify new build scripts exist and are functional.Three scripts are newly added or modified:
fix-sandbox,build-ios, andfix-metro. Ensure all referenced script files exist, are executable, and have been tested as part of this PR.Verify that:
./scripts/fix-xcode-sandbox.sh(used byfix-sandbox) exists and handles the intended iOS sandbox configuration../scripts/test-ios-build.sh(used bybuild-ios) exists and can successfully build the sample app on iOS.../scripts/fix-metro.sh(used byfix-metro) exists in the root and is compatible with the new Metro configuration.This can be confirmed via the verification script provided in the earlier comment.
11-11: Verify cross-platform compatibility of postinstall script.The
postinstallscript uses bash syntax (./scripts/fix-react-logger.sh) which will fail on Windows without additional tooling (e.g., Git Bash, WSL). The required shell scripts exist and are executable; however, developers on Windows may experience failures.Consider one of the following solutions:
- Use Node.js scripts (recommended for cross-platform): Convert shell scripts to
.jsfiles.- Use
cross-env: Add thecross-envpackage to handle platform-specific script execution.- Document Windows setup: Clearly document that Windows developers must use WSL, Git Bash, or similar environments.
Also applies to: 47-47
sample/ios/Podfile (2)
30-31: LGTM! Dynamic architecture flag properly wired.The use of
$RCT_NEW_ARCH_ENABLEDfor both:fabric_enabledand:new_arch_enabledcorrectly centralizes the architecture control.
46-57: LGTM! NEW_ARCH flag application is correct.The conditional logic properly:
- Sets
RCT_NEW_ARCH_ENABLEDbuild setting based on the flag- Preserves inherited flags with
||= ['$(inherited)']before appending- Applies
-DRCT_NEW_ARCH_ENABLED=1to both C++ and C compiler flags when enabledsample/ios/sample/PrivacyInfo.xcprivacy (1)
7-30: The privacy API declarations are correct, but clarify the purpose of this reordering.The git diff reveals these three entries were reordered—now in alphabetical order by API category: FileTimestamp, UserDefaults, then SystemBootTime. All declarations are valid for a React Native sample app, which internally uses these framework APIs.
However, since the PR title references "fix" and the change relates to a React Native version update, clarify whether this reordering was:
- An intentional alignment with React Native 0.79.6 changes, or
- A separate organizational improvement
No functional issues detected; the reason codes (C617.1, CA92.1, 35F9.1) correctly map to their respective API categories. Apple's Privacy Manifest does not enforce entry order, so this reordering has no compliance impact.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
♻️ Duplicate comments (1)
sample/ios/Podfile (1)
72-73: Remove blanket warning suppression.Setting
GCC_WARN_INHIBIT_ALL_WARNINGS = YESsuppresses all compiler warnings, which can hide legitimate issues including memory leaks, deprecated APIs, type mismatches, and potential security vulnerabilities.Apply this diff to remove the blanket suppression:
- # Additional fixes for React Native 0.81 - config.build_settings['GCC_WARN_INHIBIT_ALL_WARNINGS'] = 'YES' config.build_settings['CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER'] = 'NO'If specific warnings are causing build issues, suppress them individually with justification:
# Example: Suppress specific warning with clear reason config.build_settings['GCC_WARN_PEDANTIC'] = 'NO' # Reason: third-party pod compatibility
🧹 Nitpick comments (4)
sample/ios/Podfile (1)
30-31: Remove trailing comma.RuboCop flags the trailing comma after the last parameter as a style violation.
Apply this diff:
:fabric_enabled => $RCT_NEW_ARCH_ENABLED, - :new_arch_enabled => $RCT_NEW_ARCH_ENABLED, + :new_arch_enabled => $RCT_NEW_ARCH_ENABLEDsample/ios/sample.xcodeproj/project.pbxproj (3)
338-359: Remove orphan duplicate “[CP] Check Pods Manifest.lock” phase.This new PBXShellScriptBuildPhase isn’t attached to any target and duplicates existing checks. It’s dead weight; please delete.
- DEDDEEC392033E74160644D3 /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-sample-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - };
395-396: Code signing: Automatic with empty DEVELOPMENT_TEAM → likely CI break.Either set a valid team for Debug or disable signing for Debug to keep the sample buildable in shared environments.
Option A (use your team):
- DEVELOPMENT_TEAM = ""; + DEVELOPMENT_TEAM = 4GB94SV7D4; // or your org's teamOption B (disable Debug signing like Release):
+ CODE_SIGNING_ALLOWED = NO; + CODE_SIGNING_REQUIRED = NO; - CODE_SIGN_IDENTITY = "Apple Development"; - CODE_SIGN_STYLE = Automatic; - PROVISIONING_PROFILE_SPECIFIER = "";Also applies to: 398-398, 414-415
538-538: Tidy OTHER_LDFLAGS: remove trailing spaces (and consider keeping array form).Current value has extra spaces; trim for cleanliness. The target already supplies -ObjC/-lc++.
- OTHER_LDFLAGS = "$(inherited) "; + OTHER_LDFLAGS = "$(inherited)";Also applies to: 622-622
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
sample/ios/Podfile(3 hunks)sample/ios/sample.xcodeproj/project.pbxproj(9 hunks)
🧰 Additional context used
🪛 RuboCop (1.81.1)
sample/ios/Podfile
[convention] 31-31: Avoid comma after the last parameter of a method call.
(Style/TrailingCommaInArguments)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: test-android
- GitHub Check: test-ios
🔇 Additional comments (4)
sample/ios/Podfile (4)
17-18: LGTM!The environment variable setup correctly converts the Ruby boolean flag to the string format ('1' or '0') expected by React Native.
54-65: LGTM!The New Architecture conditional logic correctly:
- Sets build flags when enabled
- Preserves inherited compiler flags using
||=and<<- Applies
-DRCT_NEW_ARCH_ENABLED=1to both C++ and C flags- Explicitly disables when the flag is false
67-69: LGTM!These are standard React Native modular header workarounds that allow proper framework integration and module definitions.
75-77: LGTM!The C++ settings are appropriate for React Native's New Architecture:
- C++20 provides the language features required by TurboModules
- libc++ is the standard C++ library for iOS
- Explicit settings ensure consistency across all pods
| # true = Enable New Architecture (TurboModules + Fabric) | ||
| # false = Use Legacy Architecture | ||
| # ======================================== | ||
| $RCT_NEW_ARCH_ENABLED = false # ← CHANGE HERE: true ou false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix mixed language in comment.
The comment contains Portuguese text ("ou" = "or"), which should be English for consistency with the rest of the codebase.
Apply this diff:
-$RCT_NEW_ARCH_ENABLED = false # ← CHANGE HERE: true ou false
+$RCT_NEW_ARCH_ENABLED = false # ← CHANGE HERE: true or false📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| $RCT_NEW_ARCH_ENABLED = false # ← CHANGE HERE: true ou false | |
| $RCT_NEW_ARCH_ENABLED = false # ← CHANGE HERE: true or false |
🤖 Prompt for AI Agents
In sample/ios/Podfile around line 15, the inline comment on the
$RCT_NEW_ARCH_ENABLED assignment contains Portuguese "ou" and should be English;
replace "true ou false" with "true or false" so the comment reads
"$RCT_NEW_ARCH_ENABLED = false # ← CHANGE HERE: true or false" to maintain
language consistency.
| 82EB8D8E4ED3004B625C802B /* Pods_sample.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 03D4F505F8B3DA10FC759D02 /* Pods_sample.framework */; }; | ||
| D3AD968898A2D5F12A3B498E /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB81A68108700A75B9A /* PrivacyInfo.xcprivacy */; }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
Unify duplicate Pods_sample.framework references (keep a single fileRef/build file).
You now have two Pods_sample.framework entries: PBXFileReference D5881D94… + PBXBuildFile 34B3E2DD… and PBXFileReference 03D4F505… + PBXBuildFile 82EB8D8E…. Only the old build file is used in the Frameworks phase, while the new one is shown in the Frameworks group. This mismatch is brittle and can lead to stale links.
Suggested cleanup: switch the Frameworks phase to use 82EB8D8E… and remove the old pair.
*** PBXBuildFile ***
- 34B3E2DD783AD296B9753613 /* Pods_sample.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D5881D94DCC31AD3CAAE15C6 /* Pods_sample.framework */; };
+/* removed: obsolete build file for old Pods_sample.framework */
*** PBXFrameworksBuildPhase: 13B07F8C1A680F5B00A75B9A (files) ***
- 34B3E2DD783AD296B9753613 /* Pods_sample.framework in Frameworks */,
+ 82EB8D8E4ED3004B625C802B /* Pods_sample.framework in Frameworks */,
*** PBXFileReference ***
- D5881D94DCC31AD3CAAE15C6 /* Pods_sample.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_sample.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+/* removed: obsolete file reference for old Pods_sample.framework */Also applies to: 93-95
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
FILE="sample/ios/sample.xcodeproj/project.pbxproj"
echo "Build files pointing to Pods_sample.framework:"
rg -n "Pods_sample\.framework in Frameworks" "$FILE" -C1
echo -e "\nFile references named Pods_sample.framework:"
rg -nP '^[ \t]*[A-F0-9]{24} /\* Pods_sample\.framework \*/' "$FILE"Length of output: 1418
Remove the orphaned Pods_sample.framework build file entry (keep the one in use).
The verification confirms duplicate entries: the new build file 82EB8D8E (line 15) is defined but never used in any build phase, while the old build file 34B3E2DD (line 11) is the one actually referenced in the Frameworks build phase (line 61). Remove the orphaned new entry and its file reference.
Suggested cleanup:
- 82EB8D8E4ED3004B625C802B /* Pods_sample.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 03D4F505F8B3DA10FC759D02 /* Pods_sample.framework */; };
D3AD968898A2D5F12A3B498E /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB81A68108700A75B9A /* PrivacyInfo.xcprivacy */; };Also remove the orphaned file reference at line 93:
- 03D4F505F8B3DA10FC759D02 /* Pods_sample.framework */,📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| 82EB8D8E4ED3004B625C802B /* Pods_sample.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 03D4F505F8B3DA10FC759D02 /* Pods_sample.framework */; }; | |
| D3AD968898A2D5F12A3B498E /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB81A68108700A75B9A /* PrivacyInfo.xcprivacy */; }; | |
| D3AD968898A2D5F12A3B498E /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB81A68108700A75B9A /* PrivacyInfo.xcprivacy */; }; |
🤖 Prompt for AI Agents
In sample/ios/sample.xcodeproj/project.pbxproj around lines 15-16, there's an
orphaned PBXBuildFile entry for Pods_sample.framework (82EB8D8E4ED3004B625C802B)
that is not referenced by any build phase; remove that PBXBuildFile entry and
its corresponding PBXFileReference (the Pods_sample.framework fileRef at line
~93) from the project file, leaving the existing referenced build file
(34B3E2DD) intact and ensuring no build phase references are changed; after
deletion, run a quick search to confirm no remaining references to the removed
IDs exist and save the updated project.pbxproj.
| 13B07FAE1A68108700A75B9A /* sample */ = { | ||
| isa = PBXGroup; | ||
| children = ( | ||
| 0B9849D52E957E1E007A2589 /* sample-Bridging-Header.h */, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
Missing PBXFileReference for sample-Bridging-Header.h (group entry points to undefined GUID).
Group lists 0B9849D5… but there’s no PBXFileReference object. Xcode will flag this; add the file reference so the project remains consistent with SWIFT_OBJC_BRIDGING_HEADER.
*** PBXFileReference section ***
+ 0B9849D52E957E1E007A2589 /* sample-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "sample-Bridging-Header.h"; sourceTree = "<group>"; };If the header actually lives under sample/sample-Bridging-Header.h, adjust both the path above and SWIFT_OBJC_BRIDGING_HEADER accordingly.
Also applies to: 415-415, 447-447
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
# 1) Ensure the header exists where the build setting points
test -f "sample/ios/sample-Bridging-Header.h" && echo "Found: sample/ios/sample-Bridging-Header.h" || echo "Missing header at ios root"
# 2) Ensure the GUID exists as a PBXFileReference
rg -n "0B9849D52E957E1E007A2589" sample/ios/sample.xcodeproj/project.pbxproj || echo "PBXFileReference for bridging header is missing"Length of output: 106
I need to verify whether a PBXFileReference definition actually exists for this GUID. Let me check the project file structure more thoroughly.
[/run_scripts]
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Check for PBXFileReference definition (not just group reference)
echo "=== Searching for PBXFileReference definitions with this GUID ==="
rg -n "0B9849D52E957E1E007A2589.*PBXFileReference" sample/ios/sample.xcodeproj/project.pbxproj || echo "No PBXFileReference definition found"
echo ""
echo "=== Context around line 79 (group entry) ==="
sed -n '75,85p' sample/ios/sample.xcodeproj/project.pbxproj
echo ""
echo "=== Searching for pattern: GUID followed by = { isa = PBXFileReference ==="
rg -A3 "0B9849D52E957E1E007A2589.*=.*\{" sample/ios/sample.xcodeproj/project.pbxproj || echo "No PBXFileReference object definition found"
echo ""
echo "=== Also check lines 415 and 447 mentioned in review ==="
sed -n '413,417p' sample/ios/sample.xcodeproj/project.pbxproj
echo "---"
sed -n '445,449p' sample/ios/sample.xcodeproj/project.pbxprojLength of output: 1196
Add missing PBXFileReference definition for sample-Bridging-Header.h.
The GUID 0B9849D52E957E1E007A2589 is referenced in the PBXGroup at line 79 but has no corresponding PBXFileReference object definition in the project file. Xcode will flag this as a dangling reference. Add the file reference to the PBXFileReference section as suggested:
+ 0B9849D52E957E1E007A2589 /* sample-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "sample-Bridging-Header.h"; sourceTree = "<group>"; };The same build setting SWIFT_OBJC_BRIDGING_HEADER = "$(SRCROOT)/sample-Bridging-Header.h" appears at lines 415 and 447, confirming the bridging header is properly referenced in build configuration.
Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In sample/ios/sample.xcodeproj/project.pbxproj around line 79, the PBXGroup
references a GUID 0B9849D52E957E1E007A2589 for sample-Bridging-Header.h but
there is no corresponding PBXFileReference entry; add a PBXFileReference block
in the PBXFileReference section that uses that GUID, sets the correct path
("sample-Bridging-Header.h"), sourceTree ("<group>" or "SOURCE_ROOT" as
appropriate), and lastKnownFileType ("sourcecode.c.h" or "sourcecode.c.h" per
project conventions), and ensure this GUID is included in the appropriate
PBXGroup and that any existing build settings remain unchanged.
| @@ -1,10 +1,21 @@ | |||
| val usercentricsVersion = "2.23.3" | |||
| val reactNativeVersion = "+" | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does the "+" mean?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It't a common approach to use "+ " in sdk version, it's means that the host app manage what RN will be used
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
scripts/check-requirements.sh (1)
448-448: Remove duplicate exit statement.The
exit $EXIT_CODEcommand appears twice—once at line 446 (correct) and again at line 448 (redundant).echo "" exit $EXIT_CODE - -exit $EXIT_CODE
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
README.md(1 hunks)scripts/check-requirements.sh(2 hunks)
🔇 Additional comments (3)
README.md (1)
28-28: Environment requirements alignment with new architecture is clear and appropriate.The updates to minimum versions reflect Fabric/TurboModule support requirements. Requirements are consistent with the updated check-requirements.sh script and provide clear guidance (e.g., "Kotlin 2.0.21 recommended").
Also applies to: 35-36, 40-40, 42-43
scripts/check-requirements.sh (2)
150-157: Android SDK check logic appropriately handles version migration.The check gracefully handles the transition to API 34: passes on API 34, warns on API 33 with clear messaging, and fails if neither exists. This approach balances strictness with developer flexibility.
196-208: Kotlin version detection and recommendation is well-structured.The conditional logic correctly extracts the major version and recommends Kotlin 2.0.21 when version 2.0+ is detected. Messaging for missing global Kotlin is updated appropriately to reference Gradle usage.
Summary by CodeRabbit
New Features
Updates
Bug Fixes
Chores