react-native-efilli-sdk
v1.0.3
Published
Efilli SDK for React Native - Consent Management Solution
Maintainers
Readme
React Native Efilli SDK
A React Native SDK for managing user consent preferences in mobile applications, with support for both iOS and Android platforms.
Overview
The Efilli SDK provides a simple and customizable way to collect and manage user consent for data processing, tracking, and other privacy-related functions in React Native applications. The SDK handles the presentation of consent choices, storage of user preferences, and provides an easy-to-use API for integrating consent management into your app.
Features
- ✅ Cross-platform support (iOS and Android)
- ✅ Customizable consent form via WebView
- ✅ Local storage of consent preferences
- ✅ TypeScript support with type-safe API
- ✅ Comprehensive error handling
- ✅ Network connectivity detection
- ✅ Error reporting capabilities
- ✅ Simple integration with React Native applications
Requirements
- iOS 12.0+
- Android 5.0+ (API level 21+)
- React Native 0.65+
- React 17.0+
Installation
# Using npm
npm install react-native-efilli-sdk
# Using yarn
yarn add react-native-efilli-sdkiOS Setup
For iOS, the SDK uses Swift and requires your project to be configured for using Swift modules:
- Make sure you have CocoaPods installed
- Ensure your Podfile includes the use_frameworks! directive or use_modular_headers! for Swift compatibility
- Run pod install in your iOS directory
cd ios && pod installAndroid Setup
The SDK automatically includes the necessary Android configuration.
For Android, ensure you have set up React Native properly and linked the module:
# React Native 0.60+
cd android && ./gradlew cleanIntegration Guide
1. Initialize the SDK
The first step is to initialize the SDK with your consent form URL and language configuration:
import { EfilliSDK } from 'react-native-efilli-sdk';
// Initialize the SDK at app startup, typically in your App.js/App.tsx file
async function initializeConsentSDK() {
try {
await EfilliSDK.initialize({
endpointUrl: 'https://your-consent-form-url.com',
language: 'en-US'
});
console.log('Efilli SDK initialized successfully');
} catch (error) {
console.error('Failed to initialize Efilli SDK:', error);
}
}2. Display the Consent Form
When you need to show the consent form to users (e.g., at first app launch or when privacy settings need updating):
async function showConsentForm() {
try {
const result = await EfilliSDK.showConsentForm();
console.log('User consent result:', result);
// Handle the consent choices
if (result.action === 'save' || result.action === 'accept-all') {
// User accepted consent
handleAcceptedConsent(result.data);
} else if (result.action === 'reject-all') {
// User rejected optional consent
handleRejectedConsent();
}
} catch (error) {
console.error('Error showing consent form:', error);
}
}3. Check for Existing Consent
Before showing the consent form, you may want to check if the user has already provided consent:
async function checkExistingConsent() {
try {
const storedConsent = await EfilliSDK.getStoredConsent();
if (storedConsent) {
console.log('User has already provided consent:', storedConsent);
return true;
} else {
console.log('No existing consent found');
return false;
}
} catch (error) {
console.error('Error checking stored consent:', error);
return false;
}
}4. Handling Consent in Your App
function handleAcceptedConsent(categories) {
// Example: Enable features based on consent
if (categories.marketing) {
// Enable marketing features
enableMarketingTracking();
}
if (categories.functional) {
// Enable functional cookies/features
enableFunctionalFeatures();
}
// Essential features are always enabled
}
function handleRejectedConsent() {
// Disable all optional features
disableMarketingTracking();
disableFunctionalFeatures();
// Essential features remain enabled
}5. Changing Language
If your app supports multiple languages, you can update the consent form language:
async function changeLanguage(newLanguage) {
try {
await EfilliSDK.changeLanguage(newLanguage); // e.g., 'fr-FR', 'de-DE', etc.
console.log('Language changed successfully');
} catch (error) {
console.error('Error changing language:', error);
}
}6. Clearing Consent Data
For GDPR compliance or when a user wants to reset their choices:
async function clearConsentData() {
try {
await EfilliSDK.clearAllData();
console.log('Consent data cleared successfully');
} catch (error) {
console.error('Error clearing consent data:', error);
}
}API Reference
EfilliSDK
Initialization
EfilliSDK.initialize(options: EfilliOptions): Promise<void>Parameters:
options.endpointUrl(string): URL to your consent form webpageoptions.language(string): Language code for localization (e.g., 'en-US', 'fr-FR')
Checking Initialization Status
EfilliSDK.isReady(): Promise<boolean>Returns true if the SDK is initialized and ready for use.
Show Consent Form
EfilliSDK.showConsentForm(): Promise<ConsentResult>Displays the consent form WebView to the user and returns the result after user selection.
Get Stored Consent
EfilliSDK.getStoredConsent(): Promise<ConsentResult | null>Retrieves previously stored consent choices.
Change Language
EfilliSDK.changeLanguage(language: string): Promise<void>Changes the language used for the consent form.
Clear All Data
EfilliSDK.clearAllData(): Promise<void>Clears all stored consent data.
Close SDK
EfilliSDK.closeSDK(): Promise<void>Properly closes and cleans up SDK resources.
EfilliNetwork
The SDK also provides network-related functionality:
Post Error Report
EfilliNetwork.postError(errorType: string, errorMessage: string, errorStack: string): Promise<boolean>Reports errors to your error tracking system.
Get Connection Type
EfilliNetwork.getConnectionType(): Promise<string>Returns the current network connection type (e.g., 'wifi', 'cellular', 'none').
Data Models
ConsentResult
Represents the result of a consent decision.
interface ConsentResult {
action: 'save' | 'accept-all' | 'reject-all' | 'saved-consent';
data?: {
essential: boolean;
functional: boolean;
marketing: boolean;
other: boolean;
};
}Creating Your Consent Form
Your consent form webpage needs to communicate with the SDK using the JavaScript bridge. Here's how to set it up:
For iOS WebView Communication
// In your consent form HTML/JavaScript
function sendConsentToiOS(action, categories) {
const consentData = {
action: action,
data: categories
};
// Use the EfilliSDK bridge
if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.eventListener) {
window.webkit.messageHandlers.eventListener.postMessage(JSON.stringify(consentData));
} else if (window.EfilliSDK && window.EfilliSDK.sendConsent) {
window.EfilliSDK.sendConsent(consentData);
}
}For Android WebView Communication
// In your consent form HTML/JavaScript
function sendConsentToAndroid(action, categories) {
const consentData = {
action: action,
data: categories
};
// Use the Android bridge
if (window.android && window.android.postMessage) {
window.android.postMessage(JSON.stringify(consentData));
}
}
// Cross-platform function to use in your consent form
function sendConsent(action, categories) {
const consentData = {
action: action,
data: categories
};
// Detect platform and use appropriate bridge
if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.eventListener) {
// iOS
window.webkit.messageHandlers.eventListener.postMessage(JSON.stringify(consentData));
} else if (window.android && window.android.postMessage) {
// Android
window.android.postMessage(JSON.stringify(consentData));
} else if (window.EfilliSDK && window.EfilliSDK.sendConsent) {
// iOS alternative
window.EfilliSDK.sendConsent(consentData);
}
}
// Example usage
document.getElementById('accept-all-button').addEventListener('click', function() {
sendConsent('accept-all', {
essential: true,
functional: true,
marketing: true,
other: true
});
});
document.getElementById('reject-all-button').addEventListener('click', function() {
sendConsent('reject-all', {
essential: true,
functional: false,
marketing: false,
other: false
});
});
document.getElementById('save-button').addEventListener('click', function() {
sendConsent('save', {
essential: true,
functional: document.getElementById('functional-checkbox').checked,
marketing: document.getElementById('marketing-checkbox').checked,
other: document.getElementById('other-checkbox').checked
});
});Error Handling
The SDK provides detailed error handling with descriptive error messages. All methods return Promises, so errors can be caught using standard try/catch blocks.
Error types include:
INVALID_PARAMETERS: Missing or incorrect initialization parametersINVALID_URL: Malformed URL providedNOT_INITIALIZED: Attempt to use SDK before initializationSHOW_CONSENT_ERROR: Error showing the consent formNETWORK_ERROR: Network connectivity issuesINVALID_RESULT: Invalid consent result formatPARSE_ERROR: Error parsing consent data
Storage Implementation
iOS Storage
On iOS, consent data is stored using UserDefaults with a custom suite name for isolation.
Android Storage
On Android, consent data is stored using SharedPreferences with a private mode for security.
Best Practices
- Initialize Early: Initialize the SDK as early as possible in your app's lifecycle.
- Error Handling: Always implement proper error handling around SDK method calls.
- Check Existing Consent: Before showing the consent form, check if the user has already provided consent.
- Language Support: Set the appropriate language for your users based on their device settings.
- Clear Consent Data: Provide a way for users to reset their consent choices.
- Testing: Test the consent flow thoroughly, including edge cases like network failures.
Advanced Configuration
Customizing the Consent Form
The consent form is loaded from your provided URL, giving you full control over its design and behavior. You can:
- Style the form to match your app's branding
- Add custom logic for different consent flows
- Implement localization support
- Add analytics tracking (if consent is provided)
Debugging
The SDK includes extensive logging to help with debugging:
- iOS: Check the Xcode debug console for logs with the prefix "📢" or "✅"
- Android: Filter LogCat for "EfilliSDK" or "EfilliConsentActivity" tags
Example Implementation
import React, { useState, useEffect } from 'react';
import { View, Button, Text, StyleSheet, Alert } from 'react-native';
import { EfilliSDK, EfilliNetwork } from 'react-native-efilli-sdk';
const App = () => {
const [isInitialized, setIsInitialized] = useState(false);
const [consentData, setConsentData] = useState(null);
useEffect(() => {
initializeSDK();
}, []);
const initializeSDK = async () => {
try {
await EfilliSDK.initialize({
endpointUrl: 'https://example.com/consent-form',
language: 'en-US'
});
setIsInitialized(true);
// Check for existing consent
const storedConsent = await EfilliSDK.getStoredConsent();
if (storedConsent) {
setConsentData(storedConsent);
}
} catch (error) {
Alert.alert('Initialization Error', error.message);
}
};
const handleShowConsentForm = async () => {
try {
const result = await EfilliSDK.showConsentForm();
setConsentData(result);
Alert.alert('Consent Updated', `Action: ${result.action}`);
} catch (error) {
Alert.alert('Error', error.message);
}
};
const handleClearData = async () => {
try {
await EfilliSDK.clearAllData();
setConsentData(null);
Alert.alert('Success', 'Consent data cleared');
} catch (error) {
Alert.alert('Error', error.message);
}
};
return (
<View style={styles.container}>
<Text style={styles.title}>Efilli Consent Manager</Text>
<Text style={styles.status}>
Status: {isInitialized ? 'Initialized' : 'Not Initialized'}
</Text>
<Button
title="Show Consent Form"
onPress={handleShowConsentForm}
disabled={!isInitialized}
/>
<Button
title="Clear Consent Data"
onPress={handleClearData}
disabled={!isInitialized}
/>
{consentData && (
<View style={styles.consentContainer}>
<Text style={styles.consentTitle}>Consent Choices:</Text>
<Text>Action: {consentData.action}</Text>
{consentData.data && (
<>
<Text>Essential: {consentData.data.essential ? 'Yes' : 'No'}</Text>
<Text>Functional: {consentData.data.functional ? 'Yes' : 'No'}</Text>
<Text>Marketing: {consentData.data.marketing ? 'Yes' : 'No'}</Text>
<Text>Other: {consentData.data.other ? 'Yes' : 'No'}</Text>
</>
)}
</View>
)}
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 20,
justifyContent: 'center',
gap: 20,
},
title: {
fontSize: 24,
fontWeight: 'bold',
marginBottom: 20,
},
status: {
fontSize: 16,
marginBottom: 20,
},
consentContainer: {
marginTop: 20,
padding: 15,
backgroundColor: '#f5f5f5',
borderRadius: 10,
},
consentTitle: {
fontSize: 18,
fontWeight: 'bold',
marginBottom: 10,
},
});
export default App;Troubleshooting
Common Issues and Solutions
Consent Data Not Saving
- iOS: Check that your UserDefaults implementation is working properly
- Android: Verify SharedPreferences are being written correctly
WebView Not Loading
- Check your internet connection
- Verify the URL is correct and accessible
- Check for any SSL certificate issues
Language Not Changing
- Ensure the language code format is correct (e.g., 'en-US', not just 'en')
- Verify that your consent form handles language changes correctly
WebView Communication Errors
- Make sure your JavaScript code properly detects the platform
- Check that message formats match exactly what the SDK expects
License
[License details as provided by the licensee]
Support
For issues, questions, or contributions, please open an issue on the GitHub repository: https://github.com/mobile-sdk-lab/efilli-react-native-sdk-v2
© Efilli. All rights reserved.
