Signed-off-by: Matt Bruce <mbrucedogs@gmail.com>
This commit is contained in:
parent
9cd1652727
commit
d97f7e8b91
33
README.md
33
README.md
@ -6,15 +6,36 @@ A sample iOS app demonstrating the LocalData package capabilities for secure, ty
|
|||||||
|
|
||||||
This app provides interactive demos for all LocalData storage options:
|
This app provides interactive demos for all LocalData storage options:
|
||||||
|
|
||||||
| Tab | Demo | Storage Domain |
|
| Screen | Demo | Storage Domain |
|
||||||
|-----|------|----------------|
|
|--------|------|----------------|
|
||||||
| **Defaults** | Save/load/remove values | UserDefaults |
|
| **UserDefaults** | Save/load/remove values | UserDefaults |
|
||||||
| **Keychain** | Secure credentials with biometrics | Keychain |
|
| **Keychain** | Secure credentials with biometrics | Keychain |
|
||||||
| **Files** | User profiles with Codable models | File System |
|
| **File Storage** | User profiles with Codable models | File System |
|
||||||
| **Encrypted** | Encrypted logs (AES or ChaCha20) | Encrypted File System |
|
| **Encrypted Storage** | Encrypted logs (AES or ChaCha20) | Encrypted File System |
|
||||||
| **Sync** | Platform availability & sync policies | Multiple |
|
| **Platform Sync Lab** | Platform availability & sync policies | Multiple |
|
||||||
|
|
||||||
The project also includes a watchOS companion app target for watch-specific demos.
|
The project also includes a watchOS companion app target for watch-specific demos.
|
||||||
|
The watch app displays the synced user profile and the syncable setting from the Platform Sync Lab.
|
||||||
|
On iPhone launch and when the watch becomes available, the app re-sends any syncable keys so the watch updates without manual re-entry.
|
||||||
|
The watch app also requests a sync on launch when the iPhone is reachable.
|
||||||
|
|
||||||
|
## Watch Sync Handshake
|
||||||
|
|
||||||
|
This sample uses a launch-order-safe handshake so either app can start first:
|
||||||
|
|
||||||
|
1. **Watch app launches** → sends a `request_sync` message (or queues it if the iPhone is unreachable).
|
||||||
|
2. **iOS app receives the request** → replies with a snapshot of current syncable keys and updates `applicationContext`.
|
||||||
|
3. **Watch app applies the snapshot** → UI updates immediately.
|
||||||
|
|
||||||
|
This avoids requiring users to remember which app to open first.
|
||||||
|
|
||||||
|
### Where the Logic Lives
|
||||||
|
|
||||||
|
- iOS WCSession + handshake: `SecureStorageSample/SecureStorageSample/Services/WatchConnectivityService.swift`
|
||||||
|
- Bootstrap on launch: `SecureStorageSample/SecureStorageSample/SecureStorageSampleApp.swift`
|
||||||
|
- Sync policy UI lab: `SecureStorageSample/SecureStorageSample/Views/PlatformSyncDemo.swift`
|
||||||
|
- Watch WCSession + request: `SecureStorageSample/SecureStorageSample Watch App/Services/WatchConnectivityService.swift`
|
||||||
|
- Watch payload handlers: `SecureStorageSample/SecureStorageSample Watch App/Services/Handlers/`
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
|
|||||||
@ -4,7 +4,7 @@ A watchOS companion app demonstrating data synchronization with the iOS app usin
|
|||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
This watch app receives `UserProfile` data synced from the paired iPhone via `WCSession.updateApplicationContext`. It does **not** use LocalData directly for storage—instead, it displays synced data in memory.
|
This watch app receives `UserProfile` data and the syncable setting from the paired iPhone via WatchConnectivity. It does **not** use LocalData directly for storage—instead, it displays synced data in memory.
|
||||||
|
|
||||||
## Architecture
|
## Architecture
|
||||||
|
|
||||||
@ -12,6 +12,8 @@ This watch app receives `UserProfile` data synced from the paired iPhone via `WC
|
|||||||
SecureStorageSample Watch App/
|
SecureStorageSample Watch App/
|
||||||
├── ContentView.swift # Displays synced profile data
|
├── ContentView.swift # Displays synced profile data
|
||||||
├── SecureStorageSampleApp.swift
|
├── SecureStorageSampleApp.swift
|
||||||
|
├── Design/
|
||||||
|
│ └── WatchDesignConstants.swift
|
||||||
├── Protocols/
|
├── Protocols/
|
||||||
│ └── WatchDataHandling.swift # Protocol for payload handlers
|
│ └── WatchDataHandling.swift # Protocol for payload handlers
|
||||||
├── State/
|
├── State/
|
||||||
@ -20,15 +22,25 @@ SecureStorageSample Watch App/
|
|||||||
├── WatchConnectivityService.swift
|
├── WatchConnectivityService.swift
|
||||||
└── Handlers/
|
└── Handlers/
|
||||||
└── UserProfileWatchHandler.swift
|
└── UserProfileWatchHandler.swift
|
||||||
|
└── SyncableSettingWatchHandler.swift
|
||||||
```
|
```
|
||||||
|
|
||||||
## Data Flow
|
## Data Flow
|
||||||
|
|
||||||
1. **iOS app** calls `SyncHelper` when storing data with `syncPolicy: .automaticSmall` or `.manual`
|
1. **Watch app** requests a sync when it launches or becomes reachable
|
||||||
2. `SyncHelper` sends data via `WCSession.updateApplicationContext`
|
2. **iOS app** replies with a snapshot of syncable keys and updates `applicationContext`
|
||||||
3. **Watch app** receives context in `WatchConnectivityService`
|
3. **Watch app** receives context in `WatchConnectivityService`
|
||||||
4. The service dispatches each payload key to its registered `WatchDataHandling` handler
|
4. The service dispatches each payload key to its registered `WatchDataHandling` handler
|
||||||
5. `UserProfileWatchHandler` decodes the profile and updates `WatchProfileStore`
|
5. Handlers decode values and update `WatchProfileStore`
|
||||||
|
|
||||||
|
## Launch-Order-Safe Sync
|
||||||
|
|
||||||
|
The watch app handles both cases:
|
||||||
|
|
||||||
|
- If the iPhone is reachable, it sends a `request_sync` message and applies the reply payload.
|
||||||
|
- If the iPhone is not reachable, it queues a request with `transferUserInfo` and shows a badge.
|
||||||
|
|
||||||
|
This ensures users do not need to launch the apps in a specific order.
|
||||||
|
|
||||||
## Adding New Sync Payloads
|
## Adding New Sync Payloads
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user