From 3b3918f436eecfb0c5a6b0811f47cfb53a371ee6 Mon Sep 17 00:00:00 2001 From: Shofiya <86974918+Shofiya2003@users.noreply.github.com> Date: Thu, 30 Jul 2026 16:26:28 +0530 Subject: [PATCH] docs: document enableTCFConsentCollection across SDKs [LIN-2078] Add a Reading consent from a TCF CMP section to the Send Consent guide and to the Android, iOS, Flutter and React Native SDK pages, plus API reference table rows. The method derives Google Ads consent from an IAB TCF v2.2/v2.3 CMP's IABTCF_* keys; explicit setConsent values still win per signal. Supported on iOS and, from android-sdk 4.2.0, on Android. --- features/send-consent.mdx | 29 +++++++++++++++++++++++++++++ sdk/android.mdx | 11 +++++++++++ sdk/flutter.mdx | 9 +++++++++ sdk/ios.mdx | 9 +++++++++ sdk/react-native.mdx | 9 +++++++++ 5 files changed, 67 insertions(+) diff --git a/features/send-consent.mdx b/features/send-consent.mdx index 8381ab0..509fca2 100644 --- a/features/send-consent.mdx +++ b/features/send-consent.mdx @@ -94,6 +94,35 @@ Linkrunner drops any signal left `unknown` instead of sending it as a denial, so A **Consent Management Platform (CMP)** shows the consent screen at first launch and stores the answers, or you can build the screen yourself. Either way, you read the answers and report them with `setConsent`. +### Reading consent from a TCF CMP + +If your CMP is IAB TCF v2.2/v2.3 compliant, you can skip the mapping below entirely. Call `enableTCFConsentCollection(true)` before `init` and the SDK derives all three signals from the CMP's standard `IABTCF_*` keys, using Google's published purpose mapping — `hasConsentForDataUsage` from purposes 1 and 7, `hasConsentForAdsPersonalization` from purposes 3 and 4, both gated on vendor consent for Google (TCF vendor 755). + + + + ```kotlin + LinkRunner.getInstance().enableTCFConsentCollection(true) + ``` + + + ```swift + LinkrunnerSDK.shared.enableTCFConsentCollection(true) + ``` + + + ```javascript + linkrunner.enableTCFConsentCollection(true); + ``` + + + ```dart + await LinkRunner().enableTCFConsentCollection(true); + ``` + + + +Anything you set explicitly with `setConsent` still wins, per signal, so you can combine both — let the CMP answer what it knows and override the rest yourself. It is opt-in rather than automatic because interpreting a TC string on your behalf is a legal judgement: only enable it with a TCF-compliant CMP. Custom consent screens and Firebase Consent Mode do not write these keys. The flag is not persisted, so call it on every launch before `init`. If your CMP is not TCF-compliant, follow the steps below instead. + Show your consent screen at first launch, before you initialize the SDK. Ask whether they agree to their data being sent to Google for advertising, and whether they agree to it being used to personalize ads. diff --git a/sdk/android.mdx b/sdk/android.mdx index 031591b..cecd8e8 100644 --- a/sdk/android.mdx +++ b/sdk/android.mdx @@ -769,6 +769,16 @@ Google treats these as required whenever their value is known. `hasConsentForDat Consent is stored between launches. Call `setConsent` again whenever the user's consent state changes, otherwise the previous value keeps being sent after the user has withdrawn it. +### Reading consent from a TCF CMP + +If your Consent Management Platform is IAB TCF v2.2/v2.3 compliant, you can skip the mapping above. Call `enableTCFConsentCollection` before `init` and the SDK derives all three signals from the CMP's standard `IABTCF_*` keys, using Google's published purpose mapping — `hasConsentForDataUsage` from purposes 1 and 7, `hasConsentForAdsPersonalization` from purposes 3 and 4, both gated on vendor consent for Google (TCF vendor 755). + +```kotlin +LinkRunner.getInstance().enableTCFConsentCollection(true) +``` + +Anything you set explicitly with `setConsent` still wins, per signal. It is opt-in rather than automatic because interpreting a TC string on your behalf is a legal judgement — only enable it with a TCF-compliant CMP. Custom consent screens and Firebase Consent Mode do not write these keys. The flag is not persisted, so call it on every launch before `init`. + There is no extra SDK to add to your Android build. Android installs reach Google through the App Conversion API, which reads the consent signals above. @@ -965,6 +975,7 @@ Connect Firebase Cloud Messaging (FCM) with Linkrunner | `LinkRunner.getInstance().setPushToken` | Push notification setup | When FCM token is available | | `LinkRunner.getInstance().handleDeeplink` | Deep link entry points | When app is opened via a deep link | | `LinkRunner.getInstance().setConsent` | App initialization or consent flow | Before `init`, and again when consent changes | +| `LinkRunner.getInstance().enableTCFConsentCollection` | App initialization or consent flow | Before `init`, on every launch, when using a TCF CMP | | `LinkRunner.getInstance().setDisableAaidCollection` | App initialization or privacy settings | When you need to disable AAID collection | | `LinkRunner.getInstance().isAaidCollectionDisabled` | Privacy settings or compliance checks | When you need to check AAID collection status | diff --git a/sdk/flutter.mdx b/sdk/flutter.mdx index 0de8447..e5d2423 100644 --- a/sdk/flutter.mdx +++ b/sdk/flutter.mdx @@ -219,6 +219,14 @@ Set this up if you run Google App Campaigns for your iOS app. Requires `linkrunn Google treats these as required whenever their value is known. `hasConsentForDataUsage` decides whether Google may use the conversion at all, `hasConsentForAdsPersonalization` decides whether it may feed audiences and remarketing, and `isEEA` tells Google which rules apply. Set them from your app's real consent state rather than hardcoding them. **For users outside the EEA, the UK, and Switzerland, report `isEEA` as denied and leave the other two unset.** See [Send Consent](/features/send-consent). `setConsent` works on both iOS and Android. Android has no ODM SDK to add, but its installs reach Google through the App Conversion API, which reads the same signals. + + **Reading consent from a TCF CMP.** If your Consent Management Platform is IAB TCF v2.2/v2.3 compliant, you can skip the mapping above. Call `enableTCFConsentCollection` before `init` and the SDK derives all three signals from the CMP's standard `IABTCF_*` keys, using Google's published purpose mapping — `hasConsentForDataUsage` from purposes 1 and 7, `hasConsentForAdsPersonalization` from purposes 3 and 4, both gated on vendor consent for Google (TCF vendor 755). Anything set explicitly with `setConsent` still wins, per signal. + + ```dart + await LinkRunner().enableTCFConsentCollection(true); + ``` + + It is opt-in rather than automatic because interpreting a TC string on your behalf is a legal judgement — only enable it with a TCF-compliant CMP. Custom consent screens and Firebase Consent Mode do not write these keys. The flag is not persisted, so call it on every launch before `init`. Works on both iOS and Android. @@ -1037,6 +1045,7 @@ Connect APNs with Linkrunner | `LinkRunner().removePayment` | Refund flow | When payment needs to be removed | | `LinkRunner().handleDeeplink` | Deep link entry points | When app is opened via a deep link | | `LinkRunner().setConsent` | App initialization or consent flow | Before `init`, and again when consent changes | +| `LinkRunner().enableTCFConsentCollection` | App initialization or consent flow | Before `init`, on every launch, when using a TCF CMP | | `LinkRunner().setDisableAaidCollection` | App initialization or privacy settings | When you need to disable AAID collection | | `LinkRunner().isAaidCollectionDisabled` | Privacy settings or compliance checks | When you need to check AAID collection status | diff --git a/sdk/ios.mdx b/sdk/ios.mdx index 3edbf2d..3865229 100644 --- a/sdk/ios.mdx +++ b/sdk/ios.mdx @@ -199,6 +199,14 @@ Google treats these as required whenever their value is known. `hasConsentForDat Consent is stored between launches. Call `setConsent` again whenever the user's consent state changes, otherwise the previous value keeps being sent after your user has withdrawn it. +**Reading consent from a TCF CMP.** If your Consent Management Platform is IAB TCF v2.2/v2.3 compliant, you can skip the mapping above. Call `enableTCFConsentCollection` before `initialize` and the SDK derives all three signals from the CMP's standard `IABTCF_*` keys, using Google's published purpose mapping — `hasConsentForDataUsage` from purposes 1 and 7, `hasConsentForAdsPersonalization` from purposes 3 and 4, both gated on vendor consent for Google (TCF vendor 755). + +```swift +LinkrunnerSDK.shared.enableTCFConsentCollection(true) +``` + +Anything you set explicitly with `setConsent` still wins, per signal. It is opt-in rather than automatic because interpreting a TC string on your behalf is a legal judgement — only enable it with a TCF-compliant CMP. Custom consent screens and Firebase Consent Mode do not write these keys. The flag is not persisted, so call it on every launch before `initialize`. + #### Verifying your setup Initialize with `debug: true` and look for this line in the Xcode console: @@ -917,6 +925,7 @@ Connect APNs with Linkrunner | `LinkrunnerSDK.shared.setPushToken` | Push notification setup | When APNs token is available | | `LinkrunnerSDK.shared.handleDeeplink` | SceneDelegate deep link entry points | When app is opened via a deep link | | `LinkrunnerSDK.shared.setConsent` | App initialization or consent flow | Before `initialize`, and again when consent changes | +| `LinkrunnerSDK.shared.enableTCFConsentCollection` | App initialization or consent flow | Before `initialize`, on every launch, when using a TCF CMP | ## Complete Example diff --git a/sdk/react-native.mdx b/sdk/react-native.mdx index deedddc..eb1a907 100644 --- a/sdk/react-native.mdx +++ b/sdk/react-native.mdx @@ -141,6 +141,14 @@ Set this up if you run Google App Campaigns for your iOS app. Requires `rn-linkr Google treats these as required whenever their value is known. `hasConsentForDataUsage` decides whether Google may use the conversion at all, `hasConsentForAdsPersonalization` decides whether it may feed audiences and remarketing, and `isEEA` tells Google which rules apply. Set them from your app's real consent state rather than hardcoding them. **For users outside the EEA, the UK, and Switzerland, report `isEEA` as denied and leave the other two unset.** See [Send Consent](/features/send-consent). `setConsent` works on both iOS and Android. Android has no ODM SDK to add, but its installs reach Google through the App Conversion API, which reads the same signals. + + **Reading consent from a TCF CMP.** If your Consent Management Platform is IAB TCF v2.2/v2.3 compliant, you can skip the mapping above. Call `enableTCFConsentCollection` before `init` and the SDK derives all three signals from the CMP's standard `IABTCF_*` keys, using Google's published purpose mapping — `hasConsentForDataUsage` from purposes 1 and 7, `hasConsentForAdsPersonalization` from purposes 3 and 4, both gated on vendor consent for Google (TCF vendor 755). Anything set explicitly with `setConsent` still wins, per signal. + + ```javascript + linkrunner.enableTCFConsentCollection(true); + ``` + + It is opt-in rather than automatic because interpreting a TC string on your behalf is a legal judgement — only enable it with a TCF-compliant CMP. Custom consent screens and Firebase Consent Mode do not write these keys. The flag is not persisted, so call it on every launch before `init`. Works on both iOS and Android. @@ -830,6 +838,7 @@ Connect APNs with Linkrunner | `linkrunner.setPushToken` | Push notification setup | When FCM/APNs token is available | | `linkrunner.handleDeeplink` | Deep link entry points | When app is opened via a deep link | | `linkrunner.setConsent` | App initialization or consent flow | Before `init`, and again when consent changes | +| `linkrunner.enableTCFConsentCollection` | App initialization or consent flow | Before `init`, on every launch, when using a TCF CMP | ## Next Steps