Skip to content

feat: derive Google Ads consent from a TCF CMP [LIN-2078] - #39

Open
Shofiya2003 wants to merge 3 commits into
mainfrom
lin-2078-flutter-tcf-consent
Open

feat: derive Google Ads consent from a TCF CMP [LIN-2078]#39
Shofiya2003 wants to merge 3 commits into
mainfrom
lin-2078-flutter-tcf-consent

Conversation

@Shofiya2003

@Shofiya2003 Shofiya2003 commented Jul 29, 2026

Copy link
Copy Markdown
Collaborator

Adds enableTCFConsentCollection to the Flutter SDK on iOS and Android, matching the native SDKs and the React Native wrapper. Apps using an IAB TCF v2.2/v2.3 Consent Management Platform can let the SDK read the CMP's IABTCF_* keys instead of mirroring every consent change through setConsent by hand. Anything set explicitly with setConsent still wins, per signal, so an app can let the CMP supply most of the state and override one field.

await LinkRunner().enableTCFConsentCollection(true);
await LinkRunner().init('YOUR_PROJECT_TOKEN');

Platform support

iOS is handled by LinkrunnerKit's existing enableTCFConsentCollection. Android support lands in io.linkrunner:android-sdk:4.2.0 (linkrunner-labs/linkrunner-android#33), which reads the same IABTCF_* keys from the default SharedPreferences and applies the same Google purpose mapping; this PR adds the method channel handler on the Android side of the plugin. The Dart layer gates on iOS/Android only, returning early elsewhere rather than risking a MissingPluginException in the caller's app.

The iOS handler is deliberately not gated on isInitialized. The flag is meant to be set before init so the first payload already carries the CMP's values, and the native SDKs resolve consent per payload rather than snapshotting it at init.

Changes

  • lib/linkrunner.dart: public enableTCFConsentCollection([bool enabled = true]), gated on iOS and Android
  • lib/linkrunner_native_bridge.dart: method channel call
  • ios/Classes/SwiftLinkrunnerPlugin.swift: enableTCFConsentCollection case and handler
  • android/src/main/kotlin/io/linkrunner/flutter/LinkrunnerPlugin.kt: enableTCFConsentCollection case and handler, native SDK bumped to 4.2.0
  • test/tcf_consent_collection_test.dart: covers the forwarded flag, the default, the disable path, Android forwarding, and that other platforms send nothing
  • Version 4.3.0 across pubspec.yaml, the podspec and the hardcoded packageVersion

Testing

flutter test passes (7 tests). flutter analyze reports only the 15 pre-existing constant_identifier_names infos in lr_capture_payment.dart and lr_consent.dart, none from the changed files.

Follow-up

The public docs are updated in linkrunner-labs/docs (TCF section added to the Flutter, React Native, Android and iOS SDK pages and the Send Consent guide).

Adds enableTCFConsentCollection to the Flutter SDK, matching the native iOS SDK
and the React Native wrapper. Apps using an IAB TCF v2.2/v2.3 Consent Management
Platform can now let the SDK read the CMP's IABTCF_* keys instead of mirroring
every consent change through setConsent by hand.

Anything set explicitly with setConsent still wins, per signal, so an app can let
the CMP supply most of the state and override one field.

iOS only. The native Android SDK has no TCF support, so the Android side of the
plugin has no handler for this method and reaching it would throw
MissingPluginException in the caller's app. The Dart layer returns early on any
non-iOS platform, which is what the React Native wrapper does with Platform.OS,
rather than adding a no-op handler that would imply Android support.

The iOS handler is deliberately not gated on isInitialized: the flag is meant to
be set before init so the first payload already carries the CMP's values, and the
native SDK resolves consent per payload rather than snapshotting it.

Version 4.2.0 (new public API), with pubspec.yaml, the podspec and the hardcoded
packageVersion kept in step.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Extends enableTCFConsentCollection from iOS to Android, wiring both native plugins to their SDKs, adding platform-specific Flutter tests, and updating the Flutter package, CocoaPods specification, Android SDK dependency, and changelog to version 4.3.0.

Changes

TCF consent collection

Layer / File(s) Summary
Dart API and method-channel bridge
lib/linkrunner.dart, lib/linkrunner_native_bridge.dart, test/tcf_consent_collection_test.dart
Supports iOS and Android, forwards the enabled state, retains bridge error logging, and tests enabled, default, disabled, and Android behavior.
Native method-channel SDK wiring
ios/Classes/SwiftLinkrunnerPlugin.swift, android/src/main/kotlin/.../LinkrunnerPlugin.kt, android/build.gradle
Validates the enabled argument and invokes the iOS or Android SDK; Android uses io.linkrunner:android-sdk:4.2.0.
Version and changelog updates
pubspec.yaml, ios/linkrunner.podspec, CHANGELOG.md
Bumps package versions to 4.3.0 and documents Android TCF consent collection behavior.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant FlutterApp
  participant LinkRunner
  participant MethodChannel
  participant NativePlugin
  participant NativeSDK

  FlutterApp->>LinkRunner: enableTCFConsentCollection(enabled)
  LinkRunner->>MethodChannel: invoke native method
  MethodChannel->>NativePlugin: pass enabled argument
  NativePlugin->>NativeSDK: enable or disable TCF collection
  NativePlugin-->>FlutterApp: return success or error
Loading

Suggested reviewers: chetanbhosale

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: deriving Google Ads consent from a TCF CMP.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch lin-2078-flutter-tcf-consent

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

The native Android SDK (4.2.0) now derives Google Ads consent from an
IAB TCF CMP, matching iOS. Add the enableTCFConsentCollection method
channel handler to the Android plugin and drop the iOS-only gate in
Dart. Explicit setConsent values still win per signal.

Bumps io.linkrunner:android-sdk to 4.2.0 and the package to 4.3.0.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
lib/linkrunner.dart (1)

3-4: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Short-circuit web builds before checking native platforms.

On Flutter web, defaultTargetPlatform reports the browser’s OS, so a web build on iOS/Android can pass the TargetPlatform.iOS/android check and call LinkRunnerNativeBridge.enableTCFConsentCollection even though TCF collection is documented as supported only on iOS and Android. Import kIsWeb and branch it out before the platform checks at lib/linkrunner.dart:323-326; add a web test asserting no channel call is made.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/linkrunner.dart` around lines 3 - 4, Update the platform-gating logic in
LinkRunner around the TargetPlatform.iOS/android checks to import and evaluate
kIsWeb first, returning without invoking
LinkRunnerNativeBridge.enableTCFConsentCollection for web builds. Preserve the
existing native iOS and Android behavior, and add a web test verifying no
channel call occurs.

Source: MCP tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@ios/linkrunner.podspec`:
- Line 5: Update the LinkrunnerKit dependency in ios/linkrunner.podspec to the
SDK version that exports enableTCFConsentCollection, keeping it compatible with
the 4.3.0 release and the SwiftLinkrunnerPlugin.swift bridge call; if that API
is not included, remove or replace the bridge usage instead.

---

Outside diff comments:
In `@lib/linkrunner.dart`:
- Around line 3-4: Update the platform-gating logic in LinkRunner around the
TargetPlatform.iOS/android checks to import and evaluate kIsWeb first, returning
without invoking LinkRunnerNativeBridge.enableTCFConsentCollection for web
builds. Preserve the existing native iOS and Android behavior, and add a web
test verifying no channel call occurs.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: d657c107-81eb-4a84-9112-59f68805282b

📥 Commits

Reviewing files that changed from the base of the PR and between 2e99a5a and aab462d.

📒 Files selected for processing (7)
  • CHANGELOG.md
  • android/build.gradle
  • android/src/main/kotlin/io/linkrunner/flutter/LinkrunnerPlugin.kt
  • ios/linkrunner.podspec
  • lib/linkrunner.dart
  • lib/linkrunner_native_bridge.dart
  • pubspec.yaml
🚧 Files skipped from review as they are similar to previous changes (3)
  • pubspec.yaml
  • lib/linkrunner_native_bridge.dart
  • CHANGELOG.md

Comment thread ios/linkrunner.podspec
# Keep in step with pubspec.yaml — these drifted apart previously (pubspec 4.0.1
# against podspec 3.4.0).
s.version = '4.1.0'
s.version = '4.3.0'

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

pod spec cat LinkrunnerKit 4.1.0
rg -n "enableTCFConsentCollection|LinkrunnerKit" ios

Repository: RathodDarshil/linkrunner

Length of output: 203


🌐 Web query:

CocoaPods LinkrunnerKit 4.1.0 enableTCFConsentCollection

💡 Result:

There is no documented function or parameter named enableTCFConsentCollection for LinkrunnerKit 4.1.0 or any other version of the Linkrunner SDK. Official documentation for LinkrunnerKit [1][2] and its related SDK-less integrations [3][4][5] indicates that data collection preferences—specifically regarding iOS identifiers—are handled through different mechanisms: 1. IDFA Collection: You can control IDFA collection using the disableIdfa boolean flag during initialization [6][1]. 2. Apple Tracking Transparency: The SDK relies on standard Apple AppTrackingTransparency (ATT) protocols. To collect the IDFA, the app must include the NSUserTrackingUsageDescription key in its Info.plist and explicitly request tracking authorization from the user using ATTrackingManager.requestTrackingAuthorization() when the app is active [3][4]. 3. Android AAID Collection: For Android, there is a setDisableAaidCollection method to manage Google Advertising ID collection [7]. If you are seeing a reference to enableTCFConsentCollection in a specific codebase, it may be a custom internal implementation, a misunderstood parameter, or related to a third-party wrapper not present in the official Linkrunner SDK documentation.

Citations:


🌐 Web query:

"CocoaPods" "LinkrunnerKit" "4.1.0" "enableTCFConsentCollection"

💡 Result:

There is no evidence that the method enableTCFConsentCollection exists in the LinkrunnerKit CocoaPods library for iOS. Documentation for LinkrunnerKit does not list this method [1][2][3]. The specific term enableTCFDataCollection (often associated with TCF v2.2 compliance) appears in the documentation for other SDKs, such as AppsFlyer [4], but it is not part of the documented public API for LinkrunnerKit [1][2]. Linkrunner handles iOS privacy primarily through App Tracking Transparency (ATT) and IDFA management [5][6][7]. If you are looking to manage consent or privacy settings in LinkrunnerKit, the standard approach involves: 1. Requesting user permission via App Tracking Transparency (ATT) using requestTrackingAuthorization() [5]. 2. Providing the NSUserTrackingUsageDescription key in your Info.plist [5][6][8]. If you encountered a reference to enableTCFConsentCollection in a different SDK or a specific configuration, please verify the library name, as it does not match the current LinkrunnerKit implementation [1][2].

Citations:


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

printf '## Files matching linkrunner.podspec\n'
find . -path '*linkrunner.podspec' -o -path '*SwiftLinkrunnerPlugin.swift' | sort

printf '\n## podspec\n'
sed -n '1,80p' ios/linkrunner.podspec 2>/dev/null || true

printf '\n## SwiftLinkrunnerPlugin.swift references\n'
file="$(find . -path '*SwiftLinkrunnerPlugin.swift' | head -n 1 || true)"
if [ -n "$file" ]; then
  ast-grep outline "$file" 2>/dev/null | sed -n '1,80p' || true
  rg -n "enableTCFConsentCollection|LinkrunnerKit|linkrunner" "$file" -C 3
fi

printf '\n## Podfile/podspec dependency references\n'
rg -n "LinkrunnerKit|linkrunner|enableTCFConsentCollection" .

Repository: RathodDarshil/linkrunner

Length of output: 15120


🌐 Web query:

site:docs.linkrunner.io/sdk ios SDK enableTCFConsentCollection LinkRunner

💡 Result:

The Linkrunner iOS SDK does not feature a method named enableTCFConsentCollection [1][2]. Linkrunner's current iOS privacy and data collection strategy primarily focuses on managing IDFA collection via Apple's App Tracking Transparency (ATT) framework rather than TCF (Transparency and Consent Framework) consent signal integration [1][3][2]. To control data collection on iOS in the Linkrunner SDK: 1. IDFA Collection: You can control IDFA collection during SDK initialization using the disableIdfa boolean flag [1][4][5][6]. Setting this to true disables IDFA collection for iOS devices [1][4]. 2. ATT Framework: For legitimate IDFA collection, you must include the NSUserTrackingUsageDescription in your Info.plist and use Apple's ATT framework to request user permission [3][2]. 3. Other Privacy Controls: While Android and Flutter SDKs provide explicit methods like setDisableAaidCollection to manage Google Advertising ID (AAID) [7][8], the iOS SDK relies on standard native privacy practices and the aforementioned IDFA flag to manage device identifiers [1][2]. If your implementation specifically requires TCF support, ensure you are referencing the correct SDK documentation or verify if you are conflating Linkrunner with another analytics or attribution provider that supports IAB TCF standards.

Citations:


🌐 Web query:

"enableTCFConsentCollection" "LinkRunnerSDK.shared"

💡 Result:

There is no method named enableTCFConsentCollection available in the LinkRunner SDK. Based on the official LinkRunner SDK documentation for iOS, Android, React Native, and Unity, the SDK does not provide a built-in method with that specific name [1][2][3][4][5][6]. The LinkRunner SDK focuses on attribution, analytics, and user identification, and it allows for certain data collection preferences to be managed during initialization, such as disabling IDFA on iOS or AAID on Android [1][2][3][6]. If you are looking to integrate TCF (Transparency & Consent Framework) data with mobile SDKs, this is typically handled by: 1. Using a Consent Management Platform (CMP) to obtain user consent and store the TC string in the device's local storage (e.g., UserDefaults on iOS or SharedPreferences on Android) [7][8]. 2. Some third-party SDKs have specific methods to enable TCF data collection (for example, AppsFlyer uses enableTCFDataCollection) [7], but this is not a feature of the LinkRunner SDK. If your objective is to ensure compliance when using LinkRunner, you should ensure that your app's consent flow properly records the user's choices and that you are using the SDK in accordance with your organization's privacy policy and data processing agreements [9]. If you have specific requirements for TCF support, it is recommended to contact LinkRunner support directly to verify if there are undocumented ways to pass this data or if it is currently not supported.

Citations:


🌐 Web query:

"enableTCFConsentCollection" "LinkRunnerSDK.shared" site:github.com/RathodDarshil/linkrunner_flutter

💡 Result:

There is no evidence in the provided documentation that the LinkRunner SDK contains a method or property named enableTCFConsentCollection. The LinkRunner iOS SDK functions are accessed through LinkrunnerSDK.shared, but the available documentation for this interface lists methods for initialization, attribution data, user identification, event tracking, payment processing, and deep linking, with no mention of TCF (Transparency and Consent Framework) consent collection [1]. While the Android and Flutter SDKs provide methods to disable Google Advertising ID (AAID) collection [2][3] and the iOS platform allows for tracking authorization requests via ATTrackingManager [4], the provided sources do not document a specific TCF-related configuration method for LinkRunner SDKs.

Citations:


🌐 Web query:

"enableTCFConsentCollection" "LinkRunnerSDK.shared" site:github.com/RathodDarshil/linkrunner

💡 Result:

I couldn’t find any GitHub result in RathodDarshil/linkrunner for enableTCFConsentCollection or LinkRunnerSDK.shared. The closest Linkrunner docs I found mention TCF/consent-related setup in general, but not that exact API name. [1][2]

[1] (docs.linkrunner.io)
[2] (docs.linkrunner.io)

Citations:


Keep the iOS SDK dependency update in sync.

ios/linkrunner.podspec now uses 4.3.0 but still pins LinkrunnerKit to 4.1.0, while SwiftLinkrunnerPlugin.swift calls LinkrunnerSDK.shared.enableTCFConsentCollection(enabled). Upgrade the pinned SDK to the version that actually exports this API or remove/replace this bridge if the release note about iOS TCF consent support did not land.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ios/linkrunner.podspec` at line 5, Update the LinkrunnerKit dependency in
ios/linkrunner.podspec to the SDK version that exports
enableTCFConsentCollection, keeping it compatible with the 4.3.0 release and the
SwiftLinkrunnerPlugin.swift bridge call; if that API is not included, remove or
replace the bridge usage instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant