Go to file
2026-01-14 13:20:30 -06:00
SecureStorageSample Signed-off-by: Matt Bruce <mbrucedogs@gmail.com> 2026-01-14 13:20:30 -06:00
SecureStorageSample Watch App Signed-off-by: Matt Bruce <mbrucedogs@gmail.com> 2026-01-14 12:41:18 -06:00
SecureStorageSample Watch AppTests Signed-off-by: Matt Bruce <mbrucedogs@gmail.com> 2026-01-14 08:51:34 -06:00
SecureStorageSample Watch AppUITests Signed-off-by: Matt Bruce <mbrucedogs@gmail.com> 2026-01-14 08:51:34 -06:00
SecureStorageSample.xcodeproj project rename 2026-01-14 13:07:02 -06:00
SecureStorageSample.xcworkspace project rename 2026-01-14 13:07:02 -06:00
SecureStorageSampleTests project rename 2026-01-14 13:07:02 -06:00
SecureStorageSampleUITests project rename 2026-01-14 13:07:02 -06:00
SharedPackage Signed-off-by: Matt Bruce <mbrucedogs@gmail.com> 2026-01-14 12:10:12 -06:00
.gitignore Signed-off-by: Matt Bruce <mbrucedogs@gmail.com> 2026-01-13 21:20:49 -06:00
README.md project rename 2026-01-14 13:07:02 -06:00

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

  1. Open SecureStorageSample.xcodeproj
  2. Select an iOS simulator or device
  3. Build and run (⌘R)
  4. 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

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/Platform with 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.swift to avoid hardcoded strings in keys.
  • The watch app uses a handler-based WatchConnectivity layer so new payload types can be added in Services/Handlers without bloating the main service.
  • A StorageKeyCatalog sample is included to generate a security audit report of all storage keys.
  • Each StorageKey includes a description used 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.