Conversation
…pe in GPP Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
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 QodoRelease 2.26.1 with GPP framework and bug fixes
WalkthroughsDescription• Release version 2.26.1 with GPP privacy framework support • Added US National (GPP) API to Flutter, React Native, Unity • Exposed DPS metadata via new getDpsMetadata() API • Fixed Android nullable type mismatch in setGPPConsent • Fixed iOS Swift closure return type in GppData+Dict • Made TCF resurfacing period configurable (1–13 months) Diagramflowchart LR
A["Version Bump<br/>2.25.1 → 2.26.1"] --> B["GPP Framework<br/>Support Added"]
A --> C["Bug Fixes"]
B --> D["Extended to<br/>Flutter/React Native/Unity"]
B --> E["DPS Metadata<br/>API Exposed"]
C --> F["Android Nullable<br/>Type Fix"]
C --> G["iOS Closure<br/>Return Type Fix"]
C --> H["TCF Logic<br/>Improvements"]
File Changes1. android/build.gradle.kts
|
Code Review by Qodo
1.
|
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
✅ Files skipped from review due to trivial changes (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughAdded release 2.26.1 notes and bumped package/Android SDK versions; documented US National (GPP) support, expanded GPP bridge coverage and added Changes
Sequence Diagram(s)sequenceDiagram
participant AppJS as App (JS)
participant RNBridge as RN Bridge
participant NativeSDK as Native SDK
participant DPS as DPS / Metadata
AppJS->>RNBridge: call setGPPConsent(section, field, value)
RNBridge->>RNBridge: normalize null -> JSONObject.NULL
RNBridge->>NativeSDK: call setGPPConsent(section, field, normalizedValue)
NativeSDK->>DPS: persist GPP consent / update DPS metadata
NativeSDK->>RNBridge: emit onGppSectionChange / ack
RNBridge->>AppJS: resolve promise / emit event
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
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 docstrings
🧪 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: Release 2.26.1: adds GPP (US National) support, exposes GPP APIs across bridges, adds DPS metadata API, updates TCF resurfacing config, and includes several bug fixes; package and Android/iOS version bumps.
|
|
Reviewed up to commit:533a373d4f11116a52ba6951d03b1eef263fe6c0 Few more points:
Also add a unit/integration test to assert cross-platform parity for setGPPConsent with @ReactMethod
override fun setGPPConsent(sectionName: String, fieldName: String, value: ReadableMap) {
if (!value.hasKey("value")) return
val parsedValue: Any? = if (value.getType("value") == ReadableType.Null) {
null
} else {
readableMapValueToAny(value)
}
// Option 1: propagate explicit nulls to the native SDK, keeping parity with iOS
usercentricsProxy.instance.setGPPConsent(sectionName, fieldName, parsedValue)
} |
android/src/main/java/com/usercentrics/reactnative/RNUsercentricsModule.kt
Outdated
Show resolved
Hide resolved
|
CodeAnt AI finished reviewing your PR. |
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
android/src/main/java/com/usercentrics/reactnative/RNUsercentricsModule.kt (1)
151-160:⚠️ Potential issue | 🟠 MajorPlatform behavior inconsistency: iOS lacks null guard in setGPPConsent.
The Android implementation correctly prevents null values from reaching the SDK with the null guard on line 158 (
parsedValue ?: return). However, the iOS implementation atios/RNUsercentricsModule.swift:153-156always calls the SDK—passingNSNull()when the value is null or missing:
- Android: Silently returns without calling SDK when
parsedValueis null- iOS: Always calls SDK with either the actual value or
NSNull()This creates inconsistent cross-platform behavior for the same JavaScript input. Align the implementations by either adding a null check to iOS or documenting why the platforms intentionally differ.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@android/src/main/java/com/usercentrics/reactnative/RNUsercentricsModule.kt` around lines 151 - 160, The iOS implementation of setGPPConsent in RNUsercentricsModule.swift should match Android's behavior by preventing null/NSNull from being passed to the SDK; update the setGPPConsent method to parse the incoming value (the same way Android uses readableMapValueToAny analog), check if the parsed value is nil (or is NSNull) and return early if so, and only call usercentricsProxy.instance.setGPPConsent(...) when the parsed value is non-nil, thereby avoiding passing NSNull() to the SDK and aligning platform behavior with the Android setGPPConsent logic.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Outside diff comments:
In `@android/src/main/java/com/usercentrics/reactnative/RNUsercentricsModule.kt`:
- Around line 151-160: The iOS implementation of setGPPConsent in
RNUsercentricsModule.swift should match Android's behavior by preventing
null/NSNull from being passed to the SDK; update the setGPPConsent method to
parse the incoming value (the same way Android uses readableMapValueToAny
analog), check if the parsed value is nil (or is NSNull) and return early if so,
and only call usercentricsProxy.instance.setGPPConsent(...) when the parsed
value is non-nil, thereby avoiding passing NSNull() to the SDK and aligning
platform behavior with the Android setGPPConsent logic.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: df910f9f-2131-47b2-8c57-ab6019889e27
⛔ Files ignored due to path filters (3)
legacy-sample/package-lock.jsonis excluded by!**/package-lock.jsonpackage-lock.jsonis excluded by!**/package-lock.jsonsample/ios/Podfile.lockis excluded by!**/*.lock
📒 Files selected for processing (6)
CHANGELOG.mdandroid/build-legacy.gradleandroid/build.gradle.ktsandroid/src/main/java/com/usercentrics/reactnative/RNUsercentricsModule.ktios/Extensions/GppData+Dict.swiftpackage.json
Co-authored-by: codeant-ai[bot] <151821869+codeant-ai[bot]@users.noreply.github.com>
…rTCF protocol signature Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
🧹 Nitpick comments (1)
sample/ios/sampleTests/RNUsercentricsModuleTests.swift (1)
320-343: LGTM with optional improvement suggestion.The test correctly passes the new
unsavedVendorLIDecisionsparameter. For more thorough verification, consider asserting that both LI decisions parameters are captured correctly by the fake:,
✨ Optional: Add assertions for LI decisions parameters
XCTAssertEqual(.explicit_, self.fakeUsercentrics.denyAllForTCFConsentType!) XCTAssertEqual(.firstLayer, self.fakeUsercentrics.denyAllForTCFFromLayer!) + XCTAssertEqual([:], self.fakeUsercentrics.denyAllForTCFUnsavedPurposeLIDecisions!) + XCTAssertEqual([:], self.fakeUsercentrics.denyAllForTCFUnsavedVendorLIDecisions!) } reject: { _, _, _ in🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@sample/ios/sampleTests/RNUsercentricsModuleTests.swift` around lines 320 - 343, The test testDenyAllForTCF currently exercises module.denyAllForTCF with non-empty unsavedVendorLIDecisions but doesn't assert that the module forwarded the LI decision parameters to the fake; update the test to assert that fakeUsercentrics recorded the unsavedPurposeLIDecisions and unsavedVendorLIDecisions fields (e.g., compare fakeUsercentrics.lastDenyAllForTCFPurposeLIDecisions and fakeUsercentrics.lastDenyAllForTCFVendorLIDecisions or whatever properties the fake uses) match the arrays passed into module.denyAllForTCF, ensuring both LI parameters are validated alongside the existing consent assertions.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@sample/ios/sampleTests/RNUsercentricsModuleTests.swift`:
- Around line 320-343: The test testDenyAllForTCF currently exercises
module.denyAllForTCF with non-empty unsavedVendorLIDecisions but doesn't assert
that the module forwarded the LI decision parameters to the fake; update the
test to assert that fakeUsercentrics recorded the unsavedPurposeLIDecisions and
unsavedVendorLIDecisions fields (e.g., compare
fakeUsercentrics.lastDenyAllForTCFPurposeLIDecisions and
fakeUsercentrics.lastDenyAllForTCFVendorLIDecisions or whatever properties the
fake uses) match the arrays passed into module.denyAllForTCF, ensuring both LI
parameters are validated alongside the existing consent assertions.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 9d700b67-a2ba-4889-a868-265eeba14a29
📒 Files selected for processing (4)
android/src/main/java/com/usercentrics/reactnative/RNUsercentricsModule.ktios/Extensions/GppData+Dict.swiftsample/ios/sampleTests/Fake/FakeUsercentricsManager.swiftsample/ios/sampleTests/RNUsercentricsModuleTests.swift
🚧 Files skipped from review as they are similar to previous changes (2)
- android/src/main/java/com/usercentrics/reactnative/RNUsercentricsModule.kt
- ios/Extensions/GppData+Dict.swift
Add gppSignalingEnabled/gpcSignalHonoured to UsercentricsSettings mock, metadata to UsercentricsService/ServiceConsentTemplate mocks, and mspaCoveredTransaction/mspaMode to CCPASettings mock. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- DisposableEvent.callback removed; use init(callback:) instead - TCF2Settings.resurfacePeriodEnded renamed to resurfacePeriod (Int32) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- TCF2Settings: resurfacePeriodEnded (bool) renamed to resurfacePeriod (int) - CCPASettings: add mspaCoveredTransaction, mspaMode - UsercentricsSettings: add gppSignalingEnabled, gpcSignalHonoured - Update iOS/Android serializers and TypeScript models Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/models/TCF2Settings.tsx (1)
159-159:⚠️ Potential issue | 🔴 CriticalConstructor assignment references non-existent property
resurfacePeriodEnded.The property and parameter were renamed from
resurfacePeriodEndedtoresurfacePeriod, but the constructor assignment at line 159 still uses the old name. This causes the TypeScript compilation error (TS2564) and leavesthis.resurfacePerioduninitialized.🐛 Proposed fix
- this.resurfacePeriodEnded = resurfacePeriodEnded + this.resurfacePeriod = resurfacePeriod🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/models/TCF2Settings.tsx` at line 159, The constructor in class TCF2Settings assigns to the old property name resurfacePeriodEnded which no longer exists; update the constructor to assign the incoming parameter to the correct property name resurfacePeriod (ensure the constructor parameter is named resurfacePeriod or rename it accordingly) so that this.resurfacePeriod is initialized; locate the assignment in the TCF2Settings constructor and replace the reference to resurfacePeriodEnded with resurfacePeriod.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Outside diff comments:
In `@src/models/TCF2Settings.tsx`:
- Line 159: The constructor in class TCF2Settings assigns to the old property
name resurfacePeriodEnded which no longer exists; update the constructor to
assign the incoming parameter to the correct property name resurfacePeriod
(ensure the constructor parameter is named resurfacePeriod or rename it
accordingly) so that this.resurfacePeriod is initialized; locate the assignment
in the TCF2Settings constructor and replace the reference to
resurfacePeriodEnded with resurfacePeriod.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: e8df7d59-bd9c-42d8-bd1b-b0a4cac1a739
📒 Files selected for processing (6)
android/src/main/java/com/usercentrics/reactnative/extensions/UsercentricsCMPDataExtensions.ktios/Extensions/UsercentricsCMPData+Dict.swiftsrc/__tests__/mocks.tssrc/models/CCPASettings.tsxsrc/models/TCF2Settings.tsxsrc/models/UsercentricsSettings.tsx
✅ Files skipped from review due to trivial changes (1)
- src/models/CCPASettings.tsx
…uctor Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…nullable type UsercentricsDisposableEvent.init(callback:) now expects ((T?) -> Void)? in 2.26.1. Wrap the non-optional callback to handle the optional payload parameter. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
User description
Release 2.26.1
Features
getDpsMetadata()APIFixes
setGPPConsentGppData+Dict🤖 Generated with Claude Code
CodeAnt-AI Description
Release 2.26.1 for the React Native SDK
What Changed
Impact
✅ US privacy support for React Native apps✅ Clearer consent handling for Deny All flows✅ Fewer broken GPP consent updates on Android and iOS💡 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.
Summary by CodeRabbit
Release
New Features
Bug Fixes