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

This commit is contained in:
Matt Bruce 2026-01-14 12:14:16 -06:00
parent 1648e36512
commit 2b3834b3c1
2 changed files with 18 additions and 6 deletions

View File

@ -20,31 +20,41 @@ Create a single, typed, discoverable namespace for persisted app data with consi
- **StorageKey** protocol - Defines storage configuration for each data type - **StorageKey** protocol - Defines storage configuration for each data type
- **StorageRouter** actor - Main entry point coordinating all storage operations - **StorageRouter** actor - Main entry point coordinating all storage operations
- **StorageProviding** protocol - Abstraction for storage operations - **StorageProviding** protocol - Abstraction for storage operations
- **StorageKeyCatalog** protocol - Catalog of keys for auditing/validation
### Isolated Helper Classes (Actors) ### Isolated Helper Classes (Actors)
Each helper is a dedicated actor providing thread-safe access to a specific storage domain: Each helper is a dedicated actor providing thread-safe access to a specific storage domain:
- **KeychainHelper** - All keychain operations (set, get, delete, exists, deleteAll) - **KeychainHelper** - All keychain operations (set, get, delete, exists, deleteAll)
- **EncryptionHelper** - AES-256-GCM encryption with PBKDF2 key derivation - **EncryptionHelper** - AES-256-GCM or ChaCha20-Poly1305 with PBKDF2/HKDF
- **FileStorageHelper** - File system operations (read, write, delete, list, size) - **FileStorageHelper** - File system operations (read, write, delete, list, size), including App Group containers
- **UserDefaultsHelper** - UserDefaults operations with suite support - **UserDefaultsHelper** - UserDefaults operations with suite and App Group support
- **SyncHelper** - WatchConnectivity sync operations - **SyncHelper** - WatchConnectivity sync operations
### Models ### Models
- **StorageDomain** - userDefaults, keychain, fileSystem, encryptedFileSystem - **StorageDomain** - userDefaults, appGroupUserDefaults, keychain, fileSystem, encryptedFileSystem, appGroupFileSystem
- **SecurityPolicy** - none, keychain (with accessibility/accessControl), encrypted (AES-256) - **SecurityPolicy** - none, keychain (with accessibility/accessControl), encrypted (AES-256 or ChaCha20-Poly1305)
- **Serializer** - JSON, property list, raw Data, or custom encode/decode - **Serializer** - JSON, property list, raw Data, or custom encode/decode with named serializer metadata
- **KeyMaterialSource** - Identifier for external key material providers
- **PlatformAvailability** - all, phoneOnly, watchOnly, phoneWithWatchSync - **PlatformAvailability** - all, phoneOnly, watchOnly, phoneWithWatchSync
- **SyncPolicy** - never, manual, automaticSmall - **SyncPolicy** - never, manual, automaticSmall
- **KeychainAccessibility** - All 7 iOS options (whenUnlocked, afterFirstUnlock, etc.) - **KeychainAccessibility** - All 7 iOS options (whenUnlocked, afterFirstUnlock, etc.)
- **KeychainAccessControl** - All 6 options (userPresence, biometryAny, devicePasscode, etc.) - **KeychainAccessControl** - All 6 options (userPresence, biometryAny, devicePasscode, etc.)
- **FileDirectory** - documents, caches, custom URL - **FileDirectory** - documents, caches, custom URL
- **StorageError** - Comprehensive error types - **StorageError** - Comprehensive error types
- **StorageKeyDescriptor** - Audit snapshot of a keys storage metadata
- **AnyStorageKey** - Type-erased storage key for catalogs
- **AnyCodable** - Type-erased Codable for mixed-type payloads - **AnyCodable** - Type-erased Codable for mixed-type payloads
## Usage Pattern ## Usage Pattern
Apps extend StorageKeys with their own key types and use StorageRouter.shared. This follows the Notification.Name pattern for discoverable keys. Apps extend StorageKeys with their own key types and use StorageRouter.shared. This follows the Notification.Name pattern for discoverable keys.
## Audit & Validation
Apps can register a `StorageKeyCatalog` to generate audit reports and enforce key registration. Registration validates:
- Duplicate key names
- Missing descriptions
- Unregistered keys at runtime (debug assertions)
## Sync Behavior ## Sync Behavior
StorageRouter can call WCSession.updateApplicationContext for manual or automaticSmall sync policies when availability allows it. Session activation and receiving data are owned by the app. StorageRouter can call WCSession.updateApplicationContext for manual or automaticSmall sync policies when availability allows it. Session activation and receiving data are owned by the app.

View File

@ -107,6 +107,8 @@ App Group storage is explicit via `StorageDomain.appGroupUserDefaults` and `Stor
Use standard `userDefaults` or `fileSystem` for data that should remain scoped to a single target, even when App Groups are configured. Use standard `userDefaults` or `fileSystem` for data that should remain scoped to a single target, even when App Groups are configured.
For app-level configuration (App Group identifiers, keychain service identifiers, etc.), centralize constants in a shared module so keys do not hardcode string literals.
## Security Options ## Security Options
### Keychain Accessibility ### Keychain Accessibility