| SecureStorageSample | ||
| SecureStorageSample Watch App | ||
| SecureStorageSample Watch AppTests | ||
| SecureStorageSample Watch AppUITests | ||
| SecureStorageSample.xcodeproj | ||
| SecureStorageSample.xcworkspace | ||
| SecureStorageSampleTests | ||
| SecureStorageSampleUITests | ||
| SharedPackage | ||
| .gitignore | ||
| README.md | ||
SecureStorageSample
A sample iOS app demonstrating the LocalData package capabilities for secure, typed storage across multiple domains.
Features
This app provides interactive demos for all LocalData storage options:
| Tab | Demo | Storage Domain |
|---|---|---|
| Defaults | Save/load/remove values | UserDefaults |
| Keychain | Secure credentials with biometrics | Keychain |
| Files | User profiles with Codable models | File System |
| Encrypted | Encrypted logs (AES or ChaCha20) | Encrypted File System |
| Sync | Platform availability & sync policies | Multiple |
The project also includes a watchOS companion app target for watch-specific demos.
Requirements
- iOS 17.0+
- watchOS 10.0+ (companion app target)
- Xcode 15+
Getting Started
- Open
SecureStorageSample.xcodeproj - Select an iOS simulator or device
- Build and run (⌘R)
- To use App Group demos, enable the App Group entitlement for each target that should share data. The identifier is derived from the bundle ID via SharedKit constants.
Project Structure
SharedPackage/
├── Package.swift
└── Sources/
└── SharedKit/
├── Constants/
│ ├── StorageKeyNames.swift
│ └── StorageServiceIdentifiers.swift
└── Models/
└── UserProfile.swift
SecureStorageSample/
├── ContentView.swift # Tabbed navigation
├── Models/
│ ├── Credential.swift
│ └── SampleLocationData.swift
├── StorageKeys/
│ ├── UserDefaults/
│ ├── Keychain/
│ ├── FileSystem/
│ ├── EncryptedFileSystem/
│ ├── AppGroup/
│ └── Platform/
├── WatchOptimized.swift # Watch data models
├── Services/
│ ├── AppStorageCatalog.swift
│ ├── ExternalKeyMaterialProvider.swift
│ └── WatchConnectivityService.swift
└── Views/
├── UserDefaultsDemo.swift
├── KeychainDemo.swift
├── FileSystemDemo.swift
├── EncryptedStorageDemo.swift
└── PlatformSyncDemo.swift
SecureStorageSample Watch App/
├── SecureStorageSampleApp.swift
├── ContentView.swift
├── Protocols/
│ └── WatchDataHandling.swift
├── State/
│ └── WatchProfileStore.swift
└── Services/
├── WatchConnectivityService.swift
└── Handlers/
└── UserProfileWatchHandler.swift
Storage Key Examples
The app demonstrates various storage configurations:
UserDefaults
- Simple string storage with automatic sync
- App Group UserDefaults support for shared preferences
Keychain
- 7 accessibility options (whenUnlocked, afterFirstUnlock, etc.)
- 6 access control options (biometry, passcode, etc.)
File System
- Documents directory (persisted, backed up)
- Caches directory (can be purged)
- JSON and PropertyList serializers
App Group Storage
- Shared UserDefaults via App Group identifier
- Shared files in the App Group container
- Requires App Group entitlements in all participating targets
Encrypted Storage
- AES-256-GCM or ChaCha20-Poly1305 encryption
- PBKDF2 or HKDF key derivation
- Complete file protection
- External key material example via
KeyMaterialProviding - Global encryption configuration (Keychain service/account) in app
init
Platform & Sync
- Platform availability (phoneOnly, watchOnly, all)
- Sync policies (never, manual, automaticSmall)
Dependencies
- LocalData - Local package for typed secure storage
- SharedKit - Local package for shared iOS/watch models and constants
Notes
- Storage keys are now split into one file per key and grouped by domain; platform-focused keys live in
StorageKeys/Platformwith comments calling out availability/sync focus. - The shared model/constants live in
SharedPackage(SharedKit) to keep the watch/iOS data contract centralized. - Keychain service IDs and App Group identifiers are centralized in
SharedKit/Constants/StorageServiceIdentifiers.swiftto avoid hardcoded strings in keys. - The watch app uses a handler-based WatchConnectivity layer so new payload types can be added in
Services/Handlerswithout bloating the main service. - A
StorageKeyCatalogsample is included to generate a security audit report of all storage keys. - Each
StorageKeyincludes adescriptionused in audit reports. - The catalog is registered at app startup to enforce key registration and catch duplicates.
License
This sample is provided for demonstration purposes.