// // UserDefaultsDemo.swift // SecureStorgageSample // // Demonstrates UserDefaults storage with LocalData package. // import SwiftUI import LocalData struct UserDefaultsDemo: View { @State private var inputText = "" @State private var storedValue = "" @State private var appGroupStoredValue = "" @State private var statusMessage = "" @State private var isLoading = false @FocusState private var isInputFocused: Bool var body: some View { Form { Section { Text("UserDefaults stores simple data persistently. Great for preferences and small values.") .font(.caption) .foregroundStyle(.secondary) } Section("Store Value") { TextField("Enter a value", text: $inputText) .textFieldStyle(.roundedBorder) .focused($isInputFocused) Button(action: saveValue) { HStack { Image(systemName: "square.and.arrow.down") Text("Save to UserDefaults") } } .disabled(inputText.isEmpty || isLoading) } Section("Retrieve Value") { Button(action: loadValue) { HStack { Image(systemName: "arrow.down.circle") Text("Load from UserDefaults") } } .disabled(isLoading) if !storedValue.isEmpty { HStack { Text("Stored:") Spacer() Text(storedValue) .foregroundStyle(.blue) } } } Section("Remove Value") { Button(action: removeValue) { HStack { Image(systemName: "trash") Text("Remove from UserDefaults") } } .foregroundStyle(.red) .disabled(isLoading) } Section("App Group UserDefaults") { Text("Requires App Group entitlement and matching identifier in AppGroupConfiguration.") .font(.caption) .foregroundStyle(.secondary) Button(action: saveAppGroupValue) { HStack { Image(systemName: "square.and.arrow.down") Text("Save to App Group") } } .disabled(inputText.isEmpty || isLoading) Button(action: loadAppGroupValue) { HStack { Image(systemName: "arrow.down.circle") Text("Load from App Group") } } .disabled(isLoading) Button(action: removeAppGroupValue) { HStack { Image(systemName: "trash") Text("Remove from App Group") } } .foregroundStyle(.red) .disabled(isLoading) if !appGroupStoredValue.isEmpty { HStack { Text("App Group Stored:") Spacer() Text(appGroupStoredValue) .foregroundStyle(.blue) } } } if !statusMessage.isEmpty { Section { Text(statusMessage) .font(.caption) .foregroundStyle(statusMessage.contains("Error") ? .red : .green) } } Section("Key Configuration") { LabeledContent("Domain", value: "UserDefaults (standard)") LabeledContent("Security", value: "None") LabeledContent("Serializer", value: "JSON") LabeledContent("Platform", value: "All") LabeledContent("Sync Policy", value: "Automatic Small") } } .navigationTitle("UserDefaults") .navigationBarTitleDisplayMode(.inline) .toolbar { ToolbarItemGroup(placement: .keyboard) { Spacer() Button("Done") { isInputFocused = false } } } } private func saveValue() { isLoading = true Task { do { let key = StorageKeys.AppVersionKey() try await StorageRouter.shared.set(inputText, for: key) statusMessage = "✓ Saved successfully" } catch { statusMessage = "Error: \(error.localizedDescription)" } isLoading = false } } private func loadValue() { isLoading = true Task { do { let key = StorageKeys.AppVersionKey() storedValue = try await StorageRouter.shared.get(key) statusMessage = "✓ Loaded successfully" } catch StorageError.notFound { storedValue = "" statusMessage = "No value stored yet" } catch { statusMessage = "Error: \(error.localizedDescription)" } isLoading = false } } private func removeValue() { isLoading = true Task { do { let key = StorageKeys.AppVersionKey() try await StorageRouter.shared.remove(key) storedValue = "" statusMessage = "✓ Removed successfully" } catch { statusMessage = "Error: \(error.localizedDescription)" } isLoading = false } } private func saveAppGroupValue() { isLoading = true Task { do { let key = StorageKeys.AppGroupUserDefaultsKey() try await StorageRouter.shared.set(inputText, for: key) statusMessage = "✓ App Group saved successfully" } catch { statusMessage = "Error: \(error.localizedDescription)" } isLoading = false } } private func loadAppGroupValue() { isLoading = true Task { do { let key = StorageKeys.AppGroupUserDefaultsKey() appGroupStoredValue = try await StorageRouter.shared.get(key) statusMessage = "✓ App Group loaded successfully" } catch StorageError.notFound { appGroupStoredValue = "" statusMessage = "No App Group value stored yet" } catch { statusMessage = "Error: \(error.localizedDescription)" } isLoading = false } } private func removeAppGroupValue() { isLoading = true Task { do { let key = StorageKeys.AppGroupUserDefaultsKey() try await StorageRouter.shared.remove(key) appGroupStoredValue = "" statusMessage = "✓ App Group value removed" } catch { statusMessage = "Error: \(error.localizedDescription)" } isLoading = false } } } #Preview { NavigationStack { UserDefaultsDemo() } }