axeptio_sdk 2.0.19
axeptio_sdk: ^2.0.19 copied to clipboard
Axeptio flutter sdk for presenting cookies consent to the user.
Axeptio Flutter SDK Documentation #
This repository demonstrates the integration of the Axeptio Flutter SDK into mobile applications, enabling seamless consent management for both brands and publishers, tailored to your specific requirements.
Table of Contents #
- Setup and Installation
- SDK Initialization
- App Tracking Transparency (ATT) Integration
- SDK and Mobile App Responsibilities
- Retrieving and Managing Stored Consents
- TCF (Transparency & Consent Framework) Vendor Management
- TCF Global Vendor List (GVL) Integration
- Displaying the Consent Popup on Demand
- Sharing Consents with Web Views
- Clearing User Consent
- Event Handling and Customization
- Testing and Development
- Local Test
Setup and Installation #
To integrate the Axeptio SDK into your Flutter project, run the following command in your terminal:
flutter pub add axeptio_sdk
This command will automatically add the axeptio_sdk dependency to your pubspec.yaml file and download the latest available version. After running this command, the SDK will be ready for use in your Flutter project.
Alternatively, you can manually add the dependency to your pubspec.yaml under the dependencies section:
dependencies:
flutter:
sdk: flutter
axeptio_sdk: ^2.0.19
Android Setup #
Minimum SDK Version
To ensure compatibility with the Axeptio SDK, the minimum SDK version for your Flutter project must be set to API level 26 (Android 8.0 Oreo) or higher. To verify and update this setting, open your project's android/app/build.gradle file and check the following:
android {
defaultConfig {
minSdkVersion 26 // Ensure this is set to 26 or higher
}
}
Add Maven Repository and Credentials
In order to download and include the Axeptio SDK, you'll need to configure the Maven repository and authentication credentials in your android/build.gradle file. Follow these steps:
- Open the
android/build.gradlefile in your Flutter project. - In the
repositories block, add the Axeptio Maven repository URL and the required credentials for authentication.
Here is the necessary configuration to add:
allprojects {
repositories {
google()
mavenCentral()
maven {
url = uri("https://maven.pkg.github.com/axeptio/axeptio-android-sdk")
credentials {
username = System.getenv("GITHUB_USERNAME") ?: project.findProperty("github.username") as String? ?: ""
password = System.getenv("GITHUB_TOKEN") ?: project.findProperty("github.token") as String? ?: ""
}
}
}
}
GitHub Authentication & Security Setup
β οΈ SECURITY CRITICAL: Never hardcode credentials in your build files or commit them to version control.
Step 1: Generate GitHub Token
- Visit GitHub and navigate to Settings > Developer settings > Personal access tokens.
- Click Generate new token and select permissions (minimum:
read:packages). - Copy the generated token immediately (you won't see it again).
Step 2: Configure Environment Variables Set up your credentials using environment variables (recommended) or gradle.properties:
Option A: Environment Variables (Recommended)
export GITHUB_USERNAME=your_github_username
export GITHUB_TOKEN=your_generated_token
Option B: gradle.properties (Alternative)
Create ~/.gradle/gradle.properties or android/gradle.properties:
github.username=your_github_username
github.token=your_generated_token
Step 3: Update .gitignore
Ensure your .gitignore includes:
# Gradle credentials
gradle.properties
local.properties
π Security Best Practices:
- Never commit credentials to version control
- Rotate tokens regularly (quarterly recommended)
- Use minimal required permissions
- Consider using CI/CD environment variables for builds
Sync Gradle
Once you've added the repository and credentials, sync your Gradle files by either running:
flutter pub get
Or manually through Android Studio by clicking File > Sync Project with Gradle Files.
This will allow your project to fetch the necessary dependencies from the Axeptio Maven repository.
π Production Deployment Notice: For production builds, ensure you have configured CI/CD environment variables and never include credentials in your app bundle. Consider using build flavors for different environments.
iOS Setup #
Minimum iOS Version
The Axeptio SDK supports iOS versions 15.0 and higher. To ensure compatibility with the SDK, make sure your project is set to support at least iOS 15.0. To check or update the minimum iOS version, open the ios/Podfile and ensure the following line is present:
platform :ios, '15.0'
This ensures that your app targets devices running iOS 15 or later.
SDK Initialization #
To initialize the Axeptio SDK on app startup, select either brands or publishers depending on your use case. The SDK is initialized through the AxeptioService enum and requires your client_id, cookies_version, and optionally a consent_token.
Brands #
final axeptioSdkPlugin = AxeptioSdk();
await axeptioSdkPlugin.initialize(
AxeptioService.brands, // Choose either brands or publishers
"your_client_id", // Your client ID
"your_cookies_version", // Version of your cookies policy
"optional_consent_token", // Optionally pass a consent token for existing user consent
);
await axeptioSdkPlugin.setupUI(); // Setup the UI for consent management
Publisher (TCF) #
final axeptioSdkPlugin = AxeptioSdk();
await axeptioSdkPlugin.initialize(
AxeptioService.publishers, // Choose either brands or publishers
"your_client_id", // Your client ID
"your_cookies_version", // Version of your cookies policy
"optional_consent_token", // Optionally pass a consent token for existing user consent
);
await axeptioSdkPlugin.setupUI(); // Setup the UI for consent management
The setupUI() function will display the consent management UI once initialized.
App Tracking Transparency (ATT) Integration #
The Axeptio SDK does not manage App Tracking Transparency (ATT) permissions. It is the responsibility of the host app to manage the ATT flow, ensuring that the user is prompted before consent management is handled by the SDK.
Steps for Integrating ATT with Axeptio SDK:
- Add Permission Description in
Info.plist: In your iOS project, add the following key toInfo.plistto explain why the app requires user tracking:
<key>NSUserTrackingUsageDescription</key>
<string>Explain why you need user tracking</string>
- Install App Tracking Transparency Plugin:
flutter pub add app_tracking_transparency
- Request Tracking Authorization: Use the AppTrackingTransparency plugin to request permission before initializing the Axeptio SDK's consent UI. The flow checks the userβs status and takes appropriate actions based on their choice.
try {
TrackingStatus status = await AppTrackingTransparency.trackingAuthorizationStatus;
// If the status is not determined, show the system's ATT request dialog
if (status == TrackingStatus.notDetermined) {
status = await AppTrackingTransparency.requestTrackingAuthorization();
}
// If the user denied tracking, update consent status accordingly
if (status == TrackingStatus.denied) {
await axeptioSdkPlugin.setUserDeniedTracking();
} else {
// Proceed with the consent UI setup
await axeptioSdkPlugin.setupUI();
}
} on PlatformException {
// On Android, skip ATT dialog and proceed with the UI setup directly
await axeptioSdkPlugin.setupUI();
}
SDK and Mobile App Responsibilities #
The Axeptio SDK and your mobile application each have distinct responsibilities in the consent management process:
Mobile App Responsibilities:
-
Implementing ATT Flow Your app must handle the App Tracking Transparency (ATT) permission request and manage the display of the ATT prompt at the appropriate time relative to the Axeptio CMP.
-
Privacy Declaration The app must declare data collection practices accurately in App Store privacy labels.
-
Handling SDK Events The app should listen for events triggered by the SDK and adjust its behavior based on user consent status.
Axeptio SDK Responsibilities:
-
Consent Management UI The SDK is responsible for displaying the consent management interface.
-
Storing and Managing User Consent It stores and manages consent choices across sessions.
-
API Integration The SDK communicates user consent status through its API endpoints.
Note: The SDK does not manage ATT permissions. You must handle this separately as shown above.
Retrieving and Managing Stored Consents #
To retrieve stored consent choices, use UserDefaults (iOS) with the shared_preferences package.
Dart Example
import 'package:shared_preferences/shared_preferences.dart';
// Access stored consents
SharedPreferences prefs = await SharedPreferences.getInstance();
String userConsent = prefs.getString('axeptio_consent');
To retrieve stored consent choices, you can access the native preferences directly through the SDK using the following method:
import 'package:axeptio_sdk/axeptio_sdk.dart';
final result = await NativeDefaultPreferences.getDefaultPreference(
"axeptio_cookies",
);
print(result);
You can use any of the following keys depending on your needs:
Brand Keys
// Access brand-specific consent data
final cookies = await NativeDefaultPreferences.getDefaultPreference('axeptio_cookies');
final allVendors = await NativeDefaultPreferences.getDefaultPreference('axeptio_all_vendors');
final authorizedVendors = await NativeDefaultPreferences.getDefaultPreference('axeptio_authorized_vendors');
TCF Keys
// Access TCF (Transparency & Consent Framework) data
final tcString = await NativeDefaultPreferences.getDefaultPreference('IABTCF_TCString');
final vendorConsents = await NativeDefaultPreferences.getDefaultPreference('IABTCF_VendorConsents');
final gdprApplies = await NativeDefaultPreferences.getDefaultPreference('IABTCF_gdprApplies');
Bulk Operations
// Get multiple preferences at once
final preferences = await NativeDefaultPreferences.getDefaultPreferences([
'IABTCF_TCString',
'axeptio_cookies',
'IABTCF_gdprApplies'
]);
// Get all available preferences
final allPrefs = await NativeDefaultPreferences.getAllDefaultPreferences();
Available Keys
All supported preference keys are available as static lists:
// Access predefined key lists
print('Brand keys: ${NativeDefaultPreferences.brandKeys}');
print('TCF keys: ${NativeDefaultPreferences.tcfKeys}');
print('All supported keys: ${NativeDefaultPreferences.allKeys}');
β οΈ Note for Android: On Android, the SDK stores consent data in native preferences. Using
SharedPreferences.getInstance()may returnnullif the consent popup was not accepted or if the storage is not shared with Flutter. For reliable results, useNativeDefaultPreferences.getDefaultPreference()instead.
TCF (Transparency & Consent Framework) Vendor Management #
The Axeptio SDK provides comprehensive TCF (Transparency & Consent Framework) vendor consent management APIs, allowing you to programmatically access and analyze user consent decisions for individual vendors.
π± Platform Support: Available on both iOS and Android platforms.
Available APIs #
Get All Vendor Consents
Returns a complete mapping of vendor IDs to their consent status:
import 'package:axeptio_sdk/axeptio_sdk.dart';
// Get all vendor consents as a map
Map<int, bool> vendorConsents = await axeptioSdk.getVendorConsents();
// Example output: {1: true, 2: false, 50: true, 755: false}
print('Total vendors: ${vendorConsents.length}');
// Iterate through all vendor consents
vendorConsents.forEach((vendorId, isConsented) {
print('Vendor $vendorId: ${isConsented ? "Consented" : "Refused"}');
});
Get Consented Vendors
Returns a list of vendor IDs that have been granted consent:
// Get list of consented vendor IDs
List<int> consentedVendors = await axeptioSdk.getConsentedVendors();
print('Consented vendors: $consentedVendors');
print('Number of consented vendors: ${consentedVendors.length}');
// Check if specific vendors are in the consented list
if (consentedVendors.contains(1)) {
print('Google (Vendor ID 1) has consent');
}
Get Refused Vendors
Returns a list of vendor IDs that have been refused consent:
// Get list of refused vendor IDs
List<int> refusedVendors = await axeptioSdk.getRefusedVendors();
print('Refused vendors: $refusedVendors');
print('Number of refused vendors: ${refusedVendors.length}');
Check Individual Vendor Consent
Check the consent status of a specific vendor:
// Check consent for specific vendor IDs
bool googleConsent = await axeptioSdk.isVendorConsented(1); // Google
bool facebookConsent = await axeptioSdk.isVendorConsented(2); // Facebook
bool appleConsent = await axeptioSdk.isVendorConsented(755); // Apple
print('Google consent: ${googleConsent ? "β
Granted" : "β Refused"}');
print('Facebook consent: ${facebookConsent ? "β
Granted" : "β Refused"}');
print('Apple consent: ${appleConsent ? "β
Granted" : "β Refused"}');
Practical Usage Examples #
Conditional Feature Loading
Future<void> loadFeatureBasedOnConsent() async {
// Check if advertising vendor has consent
bool adConsentGranted = await axeptioSdk.isVendorConsented(50);
if (adConsentGranted) {
// Load advertising SDK
await initializeAdvertisingSDK();
} else {
print('Advertising consent not granted - skipping ad initialization');
}
}
Vendor Consent Analytics
Future<void> analyzeVendorConsents() async {
// Get comprehensive vendor consent data
Map<int, bool> allConsents = await axeptioSdk.getVendorConsents();
List<int> consented = await axeptioSdk.getConsentedVendors();
List<int> refused = await axeptioSdk.getRefusedVendors();
// Calculate consent statistics
double consentRate = consented.length / allConsents.length;
print('π Consent Analytics:');
print('Total vendors: ${allConsents.length}');
print('Consented: ${consented.length}');
print('Refused: ${refused.length}');
print('Consent rate: ${(consentRate * 100).toStringAsFixed(1)}%');
// Log specific vendor categories
List<int> adTechVendors = [1, 2, 50, 100]; // Example ad tech vendor IDs
List<int> consentedAdTech = adTechVendors.where(
(id) => consented.contains(id)
).toList();
print('Ad Tech vendors consented: $consentedAdTech');
}
Integration with Privacy Settings UI
Widget buildVendorConsentList() {
return FutureBuilder<Map<int, bool>>(
future: axeptioSdk.getVendorConsents(),
builder: (context, snapshot) {
if (!snapshot.hasData) return CircularProgressIndicator();
final vendorConsents = snapshot.data!;
return ListView.builder(
itemCount: vendorConsents.length,
itemBuilder: (context, index) {
final vendorId = vendorConsents.keys.elementAt(index);
final isConsented = vendorConsents[vendorId]!;
return ListTile(
title: Text('Vendor $vendorId'),
trailing: Icon(
isConsented ? Icons.check_circle : Icons.cancel,
color: isConsented ? Colors.green : Colors.red,
),
subtitle: Text(isConsented ? 'Consented' : 'Refused'),
);
},
);
},
);
}
Error Handling #
The vendor consent APIs include built-in error handling:
Future<void> safeVendorConsentCheck() async {
try {
// APIs return empty collections on error (never null)
Map<int, bool> consents = await axeptioSdk.getVendorConsents();
if (consents.isEmpty) {
print('No vendor consent data available');
// Handle case where no consent data exists
} else {
print('Successfully retrieved ${consents.length} vendor consents');
}
} catch (e) {
print('Error retrieving vendor consents: $e');
// Handle any unexpected errors
}
}
Platform Compatibility #
| Method | iOS | Android |
|---|---|---|
getVendorConsents() |
β Available | β Available |
getConsentedVendors() |
β Available | β Available |
getRefusedVendors() |
β Available | β Available |
isVendorConsented() |
β Available | β Available |
π Note: All vendor consent APIs are fully supported on both iOS and Android platforms.
Displaying the Consent Popup on Demand #
If needed, you can display the consent popup manually by calling the following method:
axeptioSdk.showConsentScreen();
This is useful if you want to show the popup at a specific moment based on app flow or user behavior.
Sharing Consents with Web Views #
For publishers, the SDK provides a feature to share the user's consent status with web views by appending the Axeptio token as a query parameter.
final token = await axeptioSdk.axeptioToken;
final url = await axeptioSdk.appendAxeptioTokenURL(
"https://myurl.com",
token,
);
// Will return: https://myurl.com?axeptio_token=[token]
This feature ensures that consent status is properly communicated across different parts of the application, including web content.
Clearing User Consent #
If necessary, you can clear the userβs consent choices by invoking the following method:
axeptioSdk.clearConsent();
This will reset the consent status, allowing the user to be prompted for consent again.
Event Handling and Customization #
The Axeptio SDK triggers various events that notify your app when the user takes specific actions related to consent. Use the AxeptioEventListener class to listen for these events and handle them as needed.
Example Event Listener Implementation:
var listener = AxeptioEventListener();
// Event triggered when the user closes the consent popup
listener.onPopupClosedEvent = () {
// Retrieve consents from SharedPreferences/UserDefaults
// Handle actions based on the user's consent preferences
};
// Event triggered when Google Consent Mode is updated
listener.onGoogleConsentModeUpdate = (consents) {
// Handle updates to Google Consent Mode status
// Perform specific actions based on updated consents
};
// Add and remove event listeners as necessary
var axeptioSdk = AxeptioSdk();
axeptioSdkPlugin.addEventListener(listener);
axeptioSdkPlugin.removeEventListener(listener);
Event Source Identification #
Events sent from the SDK (including those triggered via the internal WebView) include an event_source value to distinguish between App and Web contexts. This ensures analytics and KPIs are correctly attributed in the Axeptio back office.
The following values are used:
sdk-app-tcf: TCF popup inside mobile apps.sdk-web-tcf: TCF popup in web browsers.sdk-app-brands: Brands widget loaded in apps.sdk-web: Brands widget on websites.
This tagging is handled automatically by the native SDK components used under the hood in the Flutter module.
TCF Global Vendor List (GVL) Integration #
The Axeptio SDK provides comprehensive Global Vendor List (GVL) integration for resolving TCF vendor IDs to human-readable vendor names. This feature bridges the gap between numeric vendor IDs and user-friendly vendor information.
π± Platform Support: Available on both iOS and Android platforms. π Data Source: Fetches from the official IAB Global Vendor List API
Key Features #
- π Automatic Caching: 7-day intelligent caching with background refresh
- β‘ High Performance: Optimized memory usage and fast lookups
- π Offline Support: Graceful fallback when network unavailable
- π― Flexible APIs: Individual and bulk vendor name resolution
- π‘οΈ Error Handling: Robust error handling with fallback mechanisms
Loading the Global Vendor List #
Before using vendor name resolution, load the GVL data:
import 'package:axeptio_sdk/axeptio_sdk.dart';
// Load latest GVL version
final success = await axeptioSdk.loadGVL();
if (success) {
print('β
GVL loaded successfully');
} else {
print('β Failed to load GVL');
}
// Load specific GVL version (optional)
final loaded = await axeptioSdk.loadGVL(gvlVersion: "123");
Getting Vendor Names #
Single Vendor Name Resolution
// Get human-readable name for a vendor ID
final vendorName = await axeptioSdk.getVendorName(755);
print('Vendor 755: $vendorName'); // e.g., "Vendor 755: Microsoft"
// Handle missing vendors gracefully
final unknownVendor = await axeptioSdk.getVendorName(99999);
if (unknownVendor != null) {
print('Found: $unknownVendor');
} else {
print('Vendor not found in GVL');
}
Bulk Vendor Name Resolution
// Get names for multiple vendor IDs efficiently
final vendorIds = [1, 2, 755, 5175, 8690];
final vendorNames = await axeptioSdk.getVendorNames(vendorIds);
vendorNames.forEach((id, name) {
print('Vendor $id: $name');
});
// Example output:
// Vendor 1: Google LLC
// Vendor 2: Facebook Inc.
// Vendor 755: Microsoft Corporation
// Vendor 5175: Apple Inc.
Enhanced Consent Data with Names #
Get comprehensive vendor information including consent status and detailed vendor data:
// Get complete vendor information with consent status
final vendorInfos = await axeptioSdk.getVendorConsentsWithNames();
vendorInfos.forEach((id, info) {
print('${info.name}: ${info.consented ? "β
" : "β"}');
print(' Purposes: ${info.purposes}');
print(' Uses cookies: ${info.usesCookies}');
print(' Policy: ${info.policyUrl ?? "Not provided"}');
});
Cache Management #
Control GVL caching behavior for optimal performance:
// Check if GVL is currently loaded
final isLoaded = await axeptioSdk.isGVLLoaded();
print('GVL loaded: $isLoaded');
// Get current GVL version
final version = await axeptioSdk.getGVLVersion();
print('Current GVL version: ${version ?? "Not loaded"}');
// Clear GVL data from memory (preserves cache)
await axeptioSdk.unloadGVL();
// Clear all cached GVL data (forces fresh download)
await axeptioSdk.clearGVL();
Error Handling #
Future<Map<int, String>> safeGetVendorNames(List<int> vendorIds) async {
try {
// Ensure GVL is loaded
if (!await axeptioSdk.isGVLLoaded()) {
final loaded = await axeptioSdk.loadGVL();
if (!loaded) {
return <int, String>{}; // Return empty map on failure
}
}
return await axeptioSdk.getVendorNames(vendorIds);
} catch (e) {
print('Error getting vendor names: $e');
// Fallback to generic names
return Map.fromEntries(
vendorIds.map((id) => MapEntry(id, 'Vendor $id'))
);
}
}
Testing and Development #
The Axeptio Flutter SDK includes comprehensive test coverage to ensure reliability and catch regressions.
Current Test Coverage #
- Coverage: 58.9% (122/207 lines covered)
- Target: 95% coverage requirement
- Tests: 85 comprehensive tests
- Status: β οΈ Coverage below target - improvement in progress
Quick Testing Commands #
# Run all tests
flutter test
# Run tests with coverage report
flutter test --coverage
# Run specific test category
flutter test test/events/
flutter test test/model/
flutter test test/preferences/
Test Structure #
Our test suite is organized into logical components:
- Core SDK Tests: Initialization, UI management, consent handling
- Method Channel Tests: Platform communication and vendor consent APIs
- Event System Tests: Event listeners and callback handling
- Model Tests: Data validation and type conversion
- Native Preferences Tests: Cross-platform preference access
For Contributors #
- Required: All new features must include comprehensive tests
- Coverage: Maintain or improve overall test coverage
- Patterns: Follow established mock platform and testing patterns
- Validation: All tests must pass before PR acceptance
For detailed testing information, patterns, and coverage improvement strategies, see TESTING.md.
Local Test #
To test a bug fix #
- Clone the
flutter-sdkrepository. - Switch to the branch you want to test.
- Configure the widget in the sample app for either iOS or Android.
To test the version in production #
- Checkout the master branch.
Change native SDK version #
Android
In android/build.gradle, update the dependencies:
dependencies {
implementation("io.axept.android:android-sdk:2.0.8")
}
iOS
In ios/axeptio_sdk.podspec, update the version:
Pod::Spec.new do |s|
s.name = 'axeptio_sdk'
s.version = '2.0.15'
s.summary = 'AxeptioSDK for presenting cookies consent to the user'
s.homepage = '<https://github.com/axeptio/flutter-sdk>'
s.license = { :type => 'MIT', :file => '../LICENSE' }
s.author = { 'Axeptio' => 'support@axeptio.eu' }
s.source = { :git => "<https://github.com/axeptio/flutter-sdk.git>" }
s.source_files = 'Classes/**/*'
s.dependency 'Flutter'
s.dependency "AxeptioIOSSDK", "2.0.15"
s.platform = :ios, '15.0'
βοΈConfigure widget in sample app #
To configure the widget, add the project ID and version name in example/lib/main.dart:
Future<void> initSDK() async {
try {
await _axeptioSdkPlugin.initialize(
AxeptioService.publishers,
'67b63ac7d81d22bf09c09e52',
'tcf-consent-mode',
null,
);
Android
In the Android sample app, add your GitHub credentials in example/android/build.gradle:
maven {
url = uri("<https://maven.pkg.github.com/axeptio/axeptio-android-sdk>")
credentials {
username = "USER" // TODO: GITHUB USERNAME
password = "TOKEN" // TODO: GITHUB TOKEN
}
In build variants select Brands or Publisher depending on which service you want to use.
In settings.gradle.kts add your GitHub user and token.
maven {
url = uri("<https://maven.pkg.github.com/axeptio/tcf-android-sdk>")
credentials {
username = "USER" // TODO: GITHUB USERNAME
password = "TOKEN" // TODO: GITHUB TOKEN
}
}
By following this guide, you'll be able to integrate the Axeptio Flutter SDK effectively into your app, providing comprehensive consent management and ensuring compliance with privacy regulations.
For advanced configurations and further documentation, please refer to the official Axeptio documentation. We hope this guide helps you get started with the Axeptio Flutter SDK. Good luck with your integration, and thank you for choosing Axeptio!