learning_ai_common_plat/packages/swift-platform-sdk/README.md
saravanakumardb1 78000cdf6a feat(swift-sdk): add ByteLystPlatformSDK — shared Swift package for all iOS/watchOS/macOS apps
Extracts duplicated platform integration code from ChronoMind + LysnrAI into a
single Swift Package. Eliminates ~1,100+ lines of copied code per product app.

Components:
- BLPlatformConfig — product-specific configuration (productId, baseURL, bundleId)
- BLPlatformClient — generic HTTP client with auth injection, x-request-id, timeout
- BLKeychain — Keychain CRUD for secure token storage
- BLTelemetryClient — telemetry queue + batch flush (matches @bytelyst/telemetry-client)
- BLAuthClient — full auth operations (matches @bytelyst/auth-client)
- BLFeatureFlagClient — feature flag polling from platform-service /flags/poll
- BLSyncEngine — generic offline-first sync with delta pull + batch push

Platforms: iOS 17+, watchOS 10+, macOS 14+
2026-02-28 22:12:20 -08:00

157 lines
6.5 KiB
Markdown

# ByteLystPlatformSDK
Shared Swift platform client for all ByteLyst iOS/watchOS/macOS apps. Eliminates code duplication across products by providing a single source of truth for platform-service integration.
## What's Inside
| File | What It Does |
| --------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| `BLPlatformConfig` | Product-specific configuration (productId, baseURL, bundleId, appGroupId) |
| `BLPlatformClient` | Generic HTTP client with auth injection, x-request-id, timeout |
| `BLKeychain` | Keychain CRUD for secure token storage |
| `BLTelemetryClient` | Telemetry event queue + batch flush (matches `@bytelyst/telemetry-client`) |
| `BLAuthClient` | Auth operations: login, register, refresh, password ops, email verify, delete account (matches `@bytelyst/auth-client`) |
| `BLFeatureFlagClient` | Feature flag polling from platform-service `/flags/poll` |
| `BLSyncEngine` | Generic offline-first sync engine with delta pull + batch push |
## Usage
### 1. Add to Xcode Project
In Xcode: **File → Add Package Dependencies → Add Local...** → select this directory:
```
../learning_ai_common_plat/packages/swift-platform-sdk/
```
Or in `Package.swift`:
```swift
.package(path: "../learning_ai_common_plat/packages/swift-platform-sdk")
```
### 2. Configure at App Launch
```swift
import ByteLystPlatformSDK
// Create config — one per app
let config = BLPlatformConfig.fromInfoPlist(
productId: "peakpulse",
defaultBaseURL: "https://api.peakpulse.app",
bundleId: "com.saravana.peakpulse"
)
// Create shared HTTP client
let client = BLPlatformClient(config: config)
// Create services
let telemetry = BLTelemetryClient(config: config, client: client)
let auth = BLAuthClient(config: config, client: client)
let flags = BLFeatureFlagClient(config: config, client: client)
```
### 3. Telemetry
```swift
telemetry.start()
telemetry.trackEvent("info", module: "session", name: "session_started", metrics: ["elevation": 2450.0])
telemetry.trackScreen("live_tracking")
// On app background:
telemetry.stop()
```
### 4. Auth
```swift
// Login
let user = try await auth.login(email: "user@example.com", password: "secret")
// Restore on launch
await auth.restoreSession()
// Listen for state changes
auth.onAuthStateChanged = { state in
switch state {
case .loggedIn(let user): print("Hello, \(user.displayName)")
case .loggedOut: print("Signed out")
case .error(let msg): print("Auth error: \(msg)")
case .loading: print("Loading...")
}
}
```
### 5. Feature Flags
```swift
flags.start(userId: auth.accessToken != nil ? "user-id" : nil)
if flags.isEnabled("peakpulse.pro_charts") {
// Show Pro charts
}
```
### 6. Sync Engine
```swift
// Implement your product-specific adapter
struct PeakSessionSyncAdapter: BLSyncAdapter {
typealias SyncItem = PeakSessionDTO
func pullDelta(since: Date?, client: BLPlatformClient) async throws -> [PeakSessionDTO] {
var path = "/api/peak-sessions/sync"
if let since { path += "?since=\(ISO8601DateFormatter().string(from: since))" }
return try await client.request(path: path, responseType: [PeakSessionDTO].self)
}
func pushBatch(_ items: [BLOfflineQueueItem], client: BLPlatformClient) async throws -> BLBatchResult {
let body = try JSONEncoder().encode(["items": items.compactMap(\.payload)])
let (data, _) = try await client.rawRequest(path: "/api/peak-sessions/batch", method: "POST", body: body)
return try JSONDecoder().decode(BLBatchResult.self, from: data)
}
}
let syncEngine = BLSyncEngine(
config: config,
client: client,
adapter: PeakSessionSyncAdapter()
)
```
## Product Apps Using This SDK
| Product | Repo | Status |
| ---------- | ----------------------------------- | ---------------------------------------------------- |
| ChronoMind | `learning_ai_clock` | Migration from local Cloud/ files |
| LysnrAI | `learning_voice_ai_agent` | Migration from local Util/ + Auth/ files |
| PeakPulse | `learning_ai_peakpulse` | New — will use SDK from day one |
| NomGap | `learning_ai_fastgap` | Future — React Native, will use TS packages directly |
| MindLyst | `learning_multimodal_memory_agents` | Future — KMP, may need Kotlin equivalent |
## What This Replaces
Before this SDK, each iOS app had its own copy of platform integration code:
| ChronoMind (old) | LysnrAI (old) | SDK (new) |
| --------------------------------- | ------------------------------ | -------------------------------- |
| `CMTelemetryService` (139 lines) | `TelemetryService` (288 lines) | `BLTelemetryClient` |
| `CMAuthService` (359 lines) | `AuthService` (exists) | `BLAuthClient` |
| `KeychainHelper` (53 lines) | `KeychainHelper` (exists) | `BLKeychain` |
| `FeatureFlagService` (72 lines) | `FeatureFlagService` (exists) | `BLFeatureFlagClient` |
| `PlatformSyncManager` (450 lines) | Various sync files | `BLSyncEngine` + product adapter |
Total duplicated code eliminated: **~1,100+ lines per product app**.
## Design Decisions
1. **No `@MainActor`** — the SDK is thread-safe via NSLock. Product apps can wrap in `@MainActor` at the view model layer.
2. **No singletons** — product apps own the lifecycle. Create instances at app launch, inject where needed.
3. **No SwiftUI dependency** — pure Foundation. Works in watchOS, macOS, widgets, extensions.
4. **Protocol-based sync**`BLSyncAdapter` lets each product define its own DTOs and endpoints while reusing the queue/timer/conflict plumbing.
5. **Fire-and-forget telemetry** — errors never surface to the user. Matches the TypeScript package behavior.
## Platforms
- iOS 17+
- watchOS 10+
- macOS 14+