Summary: - Sources: update Migrations, Models, Protocols (+2 more) - Tests: update tests for AnyStorageKeyTests.swift, MigrationAdditionalTests.swift, MigrationIntegrationTests.swift (+3 more) - Docs: update docs for Migration, Migration_Refactor_Plan_Clean, Proposal (+1 more) Stats: - 31 files changed, 2820 insertions(+), 80 deletions(-)
2.0 KiB
2.0 KiB
LocalData Migration Guide
Overview
LocalData provides protocol-based migration support to move data from legacy storage locations to modern StorageKey definitions.
Automatic Migration
When calling get(_:) on a key, the StorageRouter automatically:
- Checks the primary location.
- If not found, evaluates
migrationdefined on the key. - If data is found in a source:
- Unsecures it using the source's old policy.
- Re-secures it using the destination key's policy.
- Stores it in the new location.
- Deletes the legacy data.
- Returns the value.
Proactive Migration (Sweep)
You can trigger a sweep of all registered keys at app launch:
try await StorageRouter.shared.registerCatalog(MyCatalog(), migrateImmediately: true)
This iterates through all keys in the catalog and calls forceMigration(for:) on each, ensuring all legacy data is consolidated.
Defining Migration Sources
Simple Legacy Migration
For 1:1 migrations, attach a SimpleLegacyMigration:
struct MyNewKey: StorageKey {
// ...
var migration: AnyStorageMigration? {
AnyStorageMigration(
SimpleLegacyMigration(
destinationKey: self,
sourceKey: .key(LegacyKey(name: "old_key_name", domain: .userDefaults(suite: nil)))
)
)
}
}
Protocol-Based Migration
For complex scenarios, attach an explicit migration:
struct MyMigration: StorageMigration {
typealias DestinationKey = MyNewKey
let destinationKey = MyNewKey()
func shouldMigrate(using router: StorageRouter, context: MigrationContext) async throws -> Bool {
try await router.exists(destinationKey)
}
func migrate(using router: StorageRouter, context: MigrationContext) async throws -> MigrationResult {
// Custom migration logic
MigrationResult(success: true)
}
}
extension MyNewKey {
var migration: AnyStorageMigration? {
AnyStorageMigration(MyMigration())
}
}