react-native-efilli-sdk
Version:
Efilli SDK for React Native - Consent Management Solution
575 lines (445 loc) • 15.3 kB
Markdown
# 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
```bash
# Using npm
npm install react-native-efilli-sdk
# Using yarn
yarn add react-native-efilli-sdk
```
### iOS Setup
For iOS, the SDK uses Swift and requires your project to be configured for using Swift modules:
1. Make sure you have CocoaPods installed
2. Ensure your Podfile includes the use_frameworks! directive or use_modular_headers! for Swift compatibility
3. Run pod install in your iOS directory
```bash
cd ios && pod install
```
### Android Setup
The SDK automatically includes the necessary Android configuration.
For Android, ensure you have set up React Native properly and linked the module:
```bash
# React Native 0.60+
cd android && ./gradlew clean
```
## Integration Guide
### 1. Initialize the SDK
The first step is to initialize the SDK with your consent form URL and language configuration:
```javascript
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):
```javascript
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:
```javascript
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
```javascript
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:
```javascript
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:
```javascript
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
```typescript
EfilliSDK.initialize(options: EfilliOptions): Promise<void>
```
Parameters:
- `options.endpointUrl` (string): URL to your consent form webpage
- `options.language` (string): Language code for localization (e.g., 'en-US', 'fr-FR')
#### Checking Initialization Status
```typescript
EfilliSDK.isReady(): Promise<boolean>
```
Returns `true` if the SDK is initialized and ready for use.
#### Show Consent Form
```typescript
EfilliSDK.showConsentForm(): Promise<ConsentResult>
```
Displays the consent form WebView to the user and returns the result after user selection.
#### Get Stored Consent
```typescript
EfilliSDK.getStoredConsent(): Promise<ConsentResult | null>
```
Retrieves previously stored consent choices.
#### Change Language
```typescript
EfilliSDK.changeLanguage(language: string): Promise<void>
```
Changes the language used for the consent form.
#### Clear All Data
```typescript
EfilliSDK.clearAllData(): Promise<void>
```
Clears all stored consent data.
#### Close SDK
```typescript
EfilliSDK.closeSDK(): Promise<void>
```
Properly closes and cleans up SDK resources.
### EfilliNetwork
The SDK also provides network-related functionality:
#### Post Error Report
```typescript
EfilliNetwork.postError(errorType: string, errorMessage: string, errorStack: string): Promise<boolean>
```
Reports errors to your error tracking system.
#### Get Connection Type
```typescript
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.
```typescript
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
```javascript
// 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
```javascript
// 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 parameters
- `INVALID_URL`: Malformed URL provided
- `NOT_INITIALIZED`: Attempt to use SDK before initialization
- `SHOW_CONSENT_ERROR`: Error showing the consent form
- `NETWORK_ERROR`: Network connectivity issues
- `INVALID_RESULT`: Invalid consent result format
- `PARSE_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
1. **Initialize Early**: Initialize the SDK as early as possible in your app's lifecycle.
2. **Error Handling**: Always implement proper error handling around SDK method calls.
3. **Check Existing Consent**: Before showing the consent form, check if the user has already provided consent.
4. **Language Support**: Set the appropriate language for your users based on their device settings.
5. **Clear Consent Data**: Provide a way for users to reset their consent choices.
6. **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:
1. Style the form to match your app's branding
2. Add custom logic for different consent flows
3. Implement localization support
4. 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
```tsx
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.