// // StorageKeys.swift // SecureStorgageSample // // Example StorageKey implementations demonstrating all variations // supported by the LocalData package. // import Foundation import LocalData // MARK: - Sample Data Models /// Simple credential model for keychain storage demo. nonisolated(unsafe) struct Credential: Codable, Sendable { let username: String let password: String } /// Location data model. nonisolated(unsafe) struct SampleLocationData: Codable, Sendable { let lat: Double let lon: Double } // MARK: - UserDefaults Keys extension StorageKeys { /// Stores the app version in standard UserDefaults. /// - Domain: UserDefaults (standard) /// - Security: None /// - Sync: Automatic for small data struct AppVersionKey: StorageKey { typealias Value = String let name = "last_app_version" let domain: StorageDomain = .userDefaults(suite: nil) let security: SecurityPolicy = .none let serializer: Serializer = .json let owner = "SampleApp" let availability: PlatformAvailability = .all let syncPolicy: SyncPolicy = .automaticSmall } /// Stores user preferences in a custom suite. /// - Domain: UserDefaults (custom suite) /// - Security: None /// - Sync: Never struct UserPreferencesKey: StorageKey { typealias Value = [String: AnyCodable] let name = "user_preferences" let domain: StorageDomain = .userDefaults(suite: "group.com.example.securestorage") let security: SecurityPolicy = .none let serializer: Serializer<[String: AnyCodable]> = .json let owner = "SampleApp" let availability: PlatformAvailability = .all let syncPolicy: SyncPolicy = .never } } // MARK: - Keychain Keys extension StorageKeys { /// Stores user credentials securely in keychain. /// Configurable accessibility and access control. struct CredentialsKey: StorageKey { typealias Value = Credential let name = "user_credentials" let domain: StorageDomain = .keychain(service: "com.example.securestorage") let security: SecurityPolicy let serializer: Serializer = .json let owner = "SampleApp" let availability: PlatformAvailability = .phoneOnly let syncPolicy: SyncPolicy = .never init(accessibility: KeychainAccessibility = .afterFirstUnlock, accessControl: KeychainAccessControl? = nil) { self.security = .keychain(accessibility: accessibility, accessControl: accessControl) } } /// Stores sensitive location data in keychain with biometric protection. struct LastLocationKey: StorageKey { typealias Value = SampleLocationData let name = "last_known_location" let domain: StorageDomain = .keychain(service: "com.example.app.security") let security: SecurityPolicy = .keychain( accessibility: .afterFirstUnlock, accessControl: .userPresence ) let serializer: Serializer = .json let owner = "SampleApp" let availability: PlatformAvailability = .phoneOnly let syncPolicy: SyncPolicy = .never } /// Stores API token in keychain. struct APITokenKey: StorageKey { typealias Value = String let name = "api_token" let domain: StorageDomain = .keychain(service: "com.example.securestorage.api") let security: SecurityPolicy = .keychain( accessibility: .whenUnlockedThisDeviceOnly, accessControl: nil ) let serializer: Serializer = .json let owner = "SampleApp" let availability: PlatformAvailability = .phoneOnly let syncPolicy: SyncPolicy = .never } } // MARK: - File System Keys extension StorageKeys { /// Stores user profile as JSON file in documents. struct UserProfileFileKey: StorageKey { typealias Value = [String: AnyCodable] let name = "user_profile.json" let domain: StorageDomain = .fileSystem(directory: .documents) let security: SecurityPolicy = .none let serializer: Serializer<[String: AnyCodable]> = .json let owner = "SampleApp" let availability: PlatformAvailability = .phoneOnly let syncPolicy: SyncPolicy = .never } /// Stores cached data files. struct CachedDataKey: StorageKey { typealias Value = Data let name = "cached_data.bin" let domain: StorageDomain = .fileSystem(directory: .caches) let security: SecurityPolicy = .none let serializer: Serializer = .data let owner = "SampleApp" let availability: PlatformAvailability = .all let syncPolicy: SyncPolicy = .never } /// Stores settings as property list. struct SettingsPlistKey: StorageKey { typealias Value = [String: AnyCodable] let name = "settings.plist" let domain: StorageDomain = .fileSystem(directory: .documents) let security: SecurityPolicy = .none let serializer: Serializer<[String: AnyCodable]> = .plist let owner = "SampleApp" let availability: PlatformAvailability = .all let syncPolicy: SyncPolicy = .never } } // MARK: - Encrypted File System Keys extension StorageKeys { /// Stores session logs with full encryption. /// Configurable PBKDF2 iterations. struct SessionLogsKey: StorageKey { typealias Value = [String] let name = "session_logs.json" let domain: StorageDomain = .encryptedFileSystem(directory: .caches) let security: SecurityPolicy let serializer: Serializer<[String]> = .json let owner = "SampleApp" let availability: PlatformAvailability = .phoneOnly let syncPolicy: SyncPolicy = .never init(iterations: Int = 10_000) { self.security = .encrypted(.aes256(keyDerivation: .pbkdf2(iterations: iterations))) } } /// Stores private notes with encryption. struct PrivateNotesKey: StorageKey { typealias Value = String let name = "private_notes.enc" let domain: StorageDomain = .encryptedFileSystem(directory: .documents) let security: SecurityPolicy = .encrypted( .aes256(keyDerivation: .pbkdf2(iterations: 50_000)) ) let serializer: Serializer = .json let owner = "SampleApp" let availability: PlatformAvailability = .phoneOnly let syncPolicy: SyncPolicy = .never } } // MARK: - Platform-Specific Keys extension StorageKeys { /// Watch-only setting for vibration. struct WatchVibrationKey: StorageKey { typealias Value = Bool let name = "watch_vibration_enabled" let domain: StorageDomain = .userDefaults(suite: nil) let security: SecurityPolicy = .none let serializer: Serializer = .json let owner = "SampleApp" let availability: PlatformAvailability = .watchOnly let syncPolicy: SyncPolicy = .never } /// Syncable setting with configurable platform and sync policy. struct SyncableSettingKey: StorageKey { typealias Value = String let name = "syncable_setting" let domain: StorageDomain = .userDefaults(suite: nil) let security: SecurityPolicy = .none let serializer: Serializer = .json let owner = "SampleApp" let availability: PlatformAvailability let syncPolicy: SyncPolicy init(availability: PlatformAvailability = .all, syncPolicy: SyncPolicy = .never) { self.availability = availability self.syncPolicy = syncPolicy } } } // MARK: - Custom Serializer Example extension StorageKeys { /// Example using custom serializer for specialized encoding. struct CustomEncodedKey: StorageKey { typealias Value = String let name = "custom_encoded" let domain: StorageDomain = .fileSystem(directory: .documents) let security: SecurityPolicy = .none let serializer: Serializer = .custom( encode: { value in // Example: Base64 encode Data(value.utf8).base64EncodedData() }, decode: { data in guard let decoded = Data(base64Encoded: data), let string = String(data: decoded, encoding: .utf8) else { throw StorageError.deserializationFailed } return string } ) let owner = "SampleApp" let availability: PlatformAvailability = .all let syncPolicy: SyncPolicy = .never } }