feat: derive Google Ads consent from a TCF CMP [LIN-2078] - #39
feat: derive Google Ads consent from a TCF CMP [LIN-2078]#39Shofiya2003 wants to merge 3 commits into
Conversation
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>
📝 WalkthroughWalkthroughExtends ChangesTCF consent collection
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
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ 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 |
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.
There was a problem hiding this comment.
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 winShort-circuit web builds before checking native platforms.
On Flutter web,
defaultTargetPlatformreports the browser’s OS, so a web build on iOS/Android can pass theTargetPlatform.iOS/androidcheck and callLinkRunnerNativeBridge.enableTCFConsentCollectioneven though TCF collection is documented as supported only on iOS and Android. ImportkIsWeband branch it out before the platform checks atlib/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
📒 Files selected for processing (7)
CHANGELOG.mdandroid/build.gradleandroid/src/main/kotlin/io/linkrunner/flutter/LinkrunnerPlugin.ktios/linkrunner.podspeclib/linkrunner.dartlib/linkrunner_native_bridge.dartpubspec.yaml
🚧 Files skipped from review as they are similar to previous changes (3)
- pubspec.yaml
- lib/linkrunner_native_bridge.dart
- CHANGELOG.md
| # 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' |
There was a problem hiding this comment.
🎯 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" iosRepository: 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:
- 1: https://docs.linkrunner.io/sdk/ios
- 2: https://docs.linkrunner.io/quickstart
- 3: https://docs.linkrunner.io/sdk-less/ios-quickstart
- 4: https://docs.linkrunner.io/sdk-less/ios-device-data
- 5: https://docs.linkrunner.io/sdk-less/api-reference
- 6: https://docs.linkrunner.io/sdk/cordova
- 7: https://docs.linkrunner.io/sdk/android
🌐 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:
- 1: https://linkrunner-01ef8e08.mintlify.app/sdk/ios
- 2: https://docs.linkrunner.io/sdk/ios
- 3: https://docs.linkrunner.io/quickstart
- 4: https://github.com/AppsFlyerSDK/appsflyer-adobe-mobile-ios-swift-extension/blob/main/Docs/SendConsentForDMACompliance.md
- 5: https://docs.linkrunner.io/sdk-less/ios-quickstart
- 6: https://docs.linkrunner.io/sdk-less/ios-device-data
- 7: https://docs.linkrunner.io/sdk-less/ios-minimal
- 8: https://linkrunner.mintlify.app/sdk/ios/installation
🏁 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:
- 1: https://docs.linkrunner.io/sdk/ios
- 2: https://docs.linkrunner.io/sdk-less/ios-device-data
- 3: https://docs.linkrunner.io/sdk/expo
- 4: https://docs.linkrunner.io/sdk/react-native
- 5: https://docs.linkrunner.io/sdk/cordova
- 6: https://docs.linkrunner.io/sdk/capacitor
- 7: https://docs.linkrunner.io/sdk/android
- 8: https://docs.linkrunner.io/sdk/flutter
🌐 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:
- 1: https://docs.linkrunner.io/sdk/android
- 2: https://docs.linkrunner.io/sdk/ios
- 3: https://docs.linkrunner.io/sdk/react-native
- 4: https://docs.linkrunner.io/sdk/web
- 5: https://docs.linkrunner.io/quickstart
- 6: https://docs.linkrunner.io/sdk/unity
- 7: https://github.com/AppsFlyerSDK/appsflyer-adobe-mobile-ios-swift-extension/blob/main/Docs/SendConsentForDMACompliance.md
- 8: https://developer-onetrust-com.ezproxy.viu.ca/onetrust/docs/iab-tcf-22-ios-next-gen
- 9: https://linkrunner.io/privacy-policy
🌐 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:
- 1: https://docs.linkrunner.io/sdk/ios
- 2: https://docs.linkrunner.io/sdk/android
- 3: https://docs.linkrunner.io/sdk/flutter
- 4: https://docs.linkrunner.io/sdk-less/ios-quickstart
🌐 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:
- 1: https://docs.linkrunner.io/sdk/flutter?utm_source=openai
- 2: https://docs.linkrunner.io/features/skadnetwork-integration?utm_source=openai
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.
Adds
enableTCFConsentCollectionto 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'sIABTCF_*keys instead of mirroring every consent change throughsetConsentby hand. Anything set explicitly withsetConsentstill wins, per signal, so an app can let the CMP supply most of the state and override one field.Platform support
iOS is handled by LinkrunnerKit's existing
enableTCFConsentCollection. Android support lands inio.linkrunner:android-sdk:4.2.0(linkrunner-labs/linkrunner-android#33), which reads the sameIABTCF_*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 aMissingPluginExceptionin the caller's app.The iOS handler is deliberately not gated on
isInitialized. The flag is meant to be set beforeinitso 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: publicenableTCFConsentCollection([bool enabled = true]), gated on iOS and Androidlib/linkrunner_native_bridge.dart: method channel callios/Classes/SwiftLinkrunnerPlugin.swift:enableTCFConsentCollectioncase and handlerandroid/src/main/kotlin/io/linkrunner/flutter/LinkrunnerPlugin.kt:enableTCFConsentCollectioncase and handler, native SDK bumped to 4.2.0test/tcf_consent_collection_test.dart: covers the forwarded flag, the default, the disable path, Android forwarding, and that other platforms send nothingpubspec.yaml, the podspec and the hardcodedpackageVersionTesting
flutter testpasses (7 tests).flutter analyzereports only the 15 pre-existingconstant_identifier_namesinfos inlr_capture_payment.dartandlr_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).