GDPR Compliance for Mobile Apps

GDPR Compliance for Mobile Apps

The General Data Protection Regulation sets strict requirements for handling EU citizens' personal data, with significant penalties for non-compliance.

GDPR Implementation for iOS:

// iOS - GDPR compliance implementation
import UIKit
import CoreData

class GDPRComplianceManager {
    
    static let shared = GDPRComplianceManager()
    private let consentStorage = ConsentStorage()
    
    // GDPR Article 6 - Lawful basis for processing
    enum LawfulBasis {
        case consent
        case contract
        case legalObligation
        case vitalInterests
        case publicTask
        case legitimateInterests
    }
    
    // GDPR Article 7 - Consent management
    class ConsentManager {
        
        struct ConsentRequest {
            let purpose: String
            let dataCategories: [DataCategory]
            let processingActivities: [ProcessingActivity]
            let retentionPeriod: TimeInterval
            let thirdPartySharing: Bool
            let internationalTransfers: Bool
        }
        
        func requestConsent(
            for request: ConsentRequest,
            completion: @escaping (ConsentResult) -> Void
        ) {
            // Create clear, specific consent request
            let consentViewController = ConsentViewController()
            
            consentViewController.configure(with: ConsentViewModel(
                title: "Data Processing Consent",
                purpose: request.purpose,
                dataCategories: request.dataCategories.map { $0.description },
                processingDetails: generateProcessingDescription(request),
                retentionInfo: "Your data will be retained for \(formatRetentionPeriod(request.retentionPeriod))",
                rightsInfo: generateRightsInformation()
            ))
            
            consentViewController.onConsent = { granted in
                if granted {
                    self.recordConsent(for: request)
                }
                completion(ConsentResult(granted: granted, timestamp: Date()))
            }
            
            presentConsentUI(consentViewController)
        }
        
        private func recordConsent(for request: ConsentRequest) {
            let consent = ConsentRecord(
                id: UUID().uuidString,
                timestamp: Date(),
                purpose: request.purpose,
                dataCategories: request.dataCategories,
                version: "1.0",
                withdrawable: true
            )
            
            consentStorage.save(consent)
            
            // Audit log for compliance
            AuditLogger.log(event: .consentGranted(consent))
        }
        
        // GDPR Article 7(3) - Withdrawal of consent
        func withdrawConsent(for consentId: String) {
            guard let consent = consentStorage.getConsent(id: consentId) else { return }
            
            // Stop processing immediately
            DataProcessingEngine.shared.stopProcessing(for: consent.dataCategories)
            
            // Delete associated data if required
            if consent.requiresDeletion {
                deleteUserData(categories: consent.dataCategories)
            }
            
            // Record withdrawal
            consentStorage.markWithdrawn(consentId: consentId)
            AuditLogger.log(event: .consentWithdrawn(consentId))
        }
    }
    
    // GDPR Article 15 - Right of access
    func handleDataAccessRequest(userId: String) async throws -> DataAccessResponse {
        var collectedData: [String: Any] = [:]
        
        // Gather all user data
        collectedData["profile"] = try await ProfileDataStore.getData(for: userId)
        collectedData["activity"] = try await ActivityLogger.getLogs(for: userId)
        collectedData["preferences"] = try await PreferencesStore.getPreferences(for: userId)
        collectedData["consents"] = consentStorage.getConsents(for: userId)
        
        // Include processing information
        let processingInfo = ProcessingInfo(
            purposes: getProcessingPurposes(),
            recipients: getDataRecipients(),
            retentionPeriods: getRetentionPeriods(),
            sources: getDataSources()
        )
        
        // Generate portable format (JSON)
        let portableData = try JSONEncoder().encode(
            PortableDataFormat(
                userData: collectedData,
                processingInfo: processingInfo,
                generatedAt: Date()
            )
        )
        
        return DataAccessResponse(
            data: portableData,
            format: .json,
            checksum: calculateChecksum(portableData)
        )
    }
    
    // GDPR Article 17 - Right to erasure (Right to be forgotten)
    func handleDeletionRequest(userId: String) async throws {
        // Verify identity
        guard try await verifyUserIdentity(userId) else {
            throw GDPRError.identityVerificationFailed
        }
        
        // Check for legal obligations to retain data
        let retentionObligations = checkRetentionObligations(userId)
        
        if retentionObligations.isEmpty {
            // Complete deletion
            try await performCompleteDeletion(userId)
        } else {
            // Partial deletion with anonymization
            try await performPartialDeletion(userId, retaining: retentionObligations)
        }
        
        // Notify third parties
        await notifyThirdPartiesOfDeletion(userId)
        
        // Audit log
        AuditLogger.log(event: .dataDeleted(userId, Date()))
    }
    
    // GDPR Article 25 - Data protection by design and by default
    class PrivacyByDesign {
        
        static func configureDataMinimization() {
            // Collect only necessary data
            UserDataCollector.shared.configure(
                collectLocation: false,
                collectDeviceId: false,
                collectAnalytics: .anonymized,
                collectCrashReports: .optIn
            )
            
            // Set privacy-friendly defaults
            UserDefaults.standard.register(defaults: [
                "analytics_enabled": false,
                "personalization_enabled": false,
                "third_party_sharing": false
            ])
        }
        
        static func implementPseudonymization() {
            // Replace identifiers with pseudonyms
            DatabaseManager.shared.enablePseudonymization(
                fields: ["email", "name", "phone"],
                algorithm: .hmacSHA256,
                key: getDerivedKey(purpose: "pseudonymization")
            )
        }
        
        static func enforceDataRetention() {
            // Automatic data expiration
            DataRetentionPolicy.configure(
                userProfiles: .years(2),
                activityLogs: .months(6),
                crashReports: .days(30),
                marketingData: .days(90)
            )
        }
    }
    
    // GDPR Article 33 - Breach notification
    class BreachNotificationHandler {
        
        func handleDataBreach(_ breach: DataBreach) {
            // Assess the breach
            let assessment = assessBreach(breach)
            
            if assessment.requiresNotification {
                // Notify supervisory authority within 72 hours
                notifySupervisoryAuthority(breach, assessment)
                
                if assessment.highRiskToIndividuals {
                    // Notify affected individuals
                    notifyAffectedUsers(breach, assessment)
                }
            }
            
            // Document the breach
            documentBreach(breach, assessment)
        }
        
        private func assessBreach(_ breach: DataBreach) -> BreachAssessment {
            return BreachAssessment(
                severity: calculateSeverity(breach),
                affectedUsers: breach.affectedUserCount,
                dataTypes: breach.compromisedDataTypes,
                requiresNotification: breach.compromisedDataTypes.contains(.sensitive),
                highRiskToIndividuals: breach.severity == .high,
                mitigationMeasures: determineMitigationMeasures(breach)
            )
        }
    }
}

Android GDPR Implementation:

// Android - GDPR compliance implementation
class GDPRComplianceManager(private val context: Context) {
    
    private val consentManager = ConsentManager(context)
    private val dataController = DataController(context)
    
    // Consent collection with granular options
    suspend fun collectConsent(): ConsentResult {
        val consentOptions = ConsentOptions(
            purposes = listOf(
                ConsentPurpose(
                    id = "analytics",
                    name = "Analytics",
                    description = "Help us improve the app by collecting usage data",
                    required = false,
                    dataTypes = listOf("app_usage", "crash_reports")
                ),
                ConsentPurpose(
                    id = "marketing",
                    name = "Marketing",
                    description = "Receive personalized offers and recommendations",
                    required = false,
                    dataTypes = listOf("preferences", "purchase_history")
                ),
                ConsentPurpose(
                    id = "essential",
                    name = "Essential Services",
                    description = "Required for app functionality",
                    required = true,
                    dataTypes = listOf("account_data", "app_settings")
                )
            )
        )
        
        return consentManager.requestConsent(consentOptions)
    }
    
    // Privacy dashboard implementation
    class PrivacyDashboard : Fragment() {
        
        override fun onCreateView(
            inflater: LayoutInflater,
            container: ViewGroup?,
            savedInstanceState: Bundle?
        ): View {
            return ComposeView(requireContext()).apply {
                setContent {
                    PrivacyDashboardScreen()
                }
            }
        }
        
        @Composable
        fun PrivacyDashboardScreen() {
            Column(modifier = Modifier.fillMaxSize().padding(16.dp)) {
                Text(
                    "Privacy Settings",
                    style = MaterialTheme.typography.h4
                )
                
                Spacer(modifier = Modifier.height(16.dp))
                
                // Consent management
                ConsentManagementCard()
                
                // Data access
                DataAccessCard()
                
                // Data portability
                DataPortabilityCard()
                
                // Account deletion
                AccountDeletionCard()
            }
        }
        
        @Composable
        fun ConsentManagementCard() {
            Card(
                modifier = Modifier.fillMaxWidth().padding(vertical = 8.dp)
            ) {
                Column(modifier = Modifier.padding(16.dp)) {
                    Text("Manage Consents", style = MaterialTheme.typography.h6)
                    
                    val consents = remember { consentManager.getActiveConsents() }
                    
                    consents.forEach { consent ->
                        Row(
                            modifier = Modifier.fillMaxWidth(),
                            horizontalArrangement = Arrangement.SpaceBetween
                        ) {
                            Text(consent.purpose)
                            Switch(
                                checked = consent.granted,
                                onCheckedChange = { granted ->
                                    if (granted) {
                                        consentManager.grantConsent(consent.id)
                                    } else {
                                        consentManager.withdrawConsent(consent.id)
                                    }
                                }
                            )
                        }
                    }
                }
            }
        }
    }
    
    // Data portability implementation
    class DataPortabilityManager(private val context: Context) {
        
        suspend fun exportUserData(format: ExportFormat): Uri {
            val userData = collectAllUserData()
            
            return when (format) {
                ExportFormat.JSON -> exportAsJson(userData)
                ExportFormat.CSV -> exportAsCsv(userData)
                ExportFormat.XML -> exportAsXml(userData)
            }
        }
        
        private suspend fun collectAllUserData(): UserDataPackage {
            return UserDataPackage(
                profile = getProfileData(),
                activities = getActivityData(),
                preferences = getPreferences(),
                consents = getConsentHistory(),
                generatedAt = System.currentTimeMillis()
            )
        }
        
        private suspend fun exportAsJson(data: UserDataPackage): Uri {
            val gson = GsonBuilder()
                .setPrettyPrinting()
                .setDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")
                .create()
            
            val json = gson.toJson(data)
            
            // Save to secure location
            val file = File(context.getExternalFilesDir(null), "user_data_export.json")
            
            val encryptedFile = EncryptedFile.Builder(
                context,
                file,
                MasterKey.Builder(context).build(),
                EncryptedFile.FileEncryptionScheme.AES256_GCM_HKDF_4KB
            ).build()
            
            encryptedFile.openFileOutput().use { output ->
                output.write(json.toByteArray())
            }
            
            return FileProvider.getUriForFile(
                context,
                "${context.packageName}.fileprovider",
                file
            )
        }
    }
}