Signed-off-by: Matt Bruce <mbrucedogs@gmail.com>

This commit is contained in:
Matt Bruce 2026-01-14 17:44:20 -06:00
parent 14e2235031
commit c5a79e3f8c
3 changed files with 34 additions and 2 deletions

View File

@ -121,6 +121,11 @@ The app demonstrates various storage configurations:
- Sync policies (never, manual, automaticSmall)
- Global sync configuration (max file size) in app `init`
### Data Migration
- **Fallback**: Automatically moves data from `LegacyMigrationSourceKey` to `ModernMigrationDestinationKey` on first access.
- **Manual Sweep**: Explicitly triggers a "drain" of legacy keys to the Keychain using `StorageRouter.shared.migrate(for:)`.
- **Startup Sweep**: Automatically cleanses all registered legacy keys at app launch via `registerCatalog(..., migrateImmediately: true)`.
## Global Configuration
The app demonstrates how to configure the `LocalData` library globally during startup in `SecureStorageSampleApp.swift`:

View File

@ -48,7 +48,7 @@ struct SecureStorageSampleApp: App {
await StorageRouter.shared.updateStorageConfiguration(storageConfig)
do {
try await StorageRouter.shared.registerCatalog(AppStorageCatalog.self)
try await StorageRouter.shared.registerCatalog(AppStorageCatalog.self, migrateImmediately: true)
} catch {
assertionFailure("Storage catalog registration failed: \(error)")
}

View File

@ -45,7 +45,17 @@ struct MigrationDemo: View {
}
}
Section("Step 3: Verify Cleanup") {
Section("Step 3: Proactive Sweep (Drain)") {
Text("Even if the modern key already has data, you can force a 'Sweep' of legacy sources. Try saving a NEW value to Legacy, then click Drain.")
.font(.caption)
Button(action: runManualMigration) {
Label("Drain Migration Sources", systemImage: "arrow.up.circle.badge.clock")
}
.disabled(isLoading)
}
Section("Step 4: Verify Cleanup") {
Text("Check if the data was actually removed from UserDefaults after migration.")
.font(.caption)
@ -101,6 +111,23 @@ struct MigrationDemo: View {
}
}
private func runManualMigration() {
isLoading = true
statusMessage = "Draining migration sources..."
Task {
do {
let key = StorageKeys.ModernMigrationDestinationKey()
try await StorageRouter.shared.migrate(for: key)
// Refresh modern value display
modernValue = try await StorageRouter.shared.get(key)
statusMessage = "✓ Proactive migration complete. Legacy data drained into Keychain."
} catch {
statusMessage = "Error: \(error.localizedDescription)"
}
isLoading = false
}
}
private func checkLegacyExists() {
isLoading = true
Task {