# Cloud Music Streaming — iOS Port Spec ## Overview Port the Chad Music cloud streaming feature from macOS MixBoard to iOS MixBoard. Users connect to a self-hosted Chad Music REST API server (Tailnet) to browse and stream their cloud music library. Cloud tracks can be mixed into the same playlists as local tracks. ## Architecture ### New Files (5) | File | Location | Purpose | |------|----------|---------| | ChadMusic.swift | Models/ | API response models (ChadCategory, ChadAlbum, ChadTrack, ChadStats, ChadCategoryType) | | ChadMusicAPIClient.swift | Services/ | HTTP client — Bearer auth, URL composition, JSON decoding | | StreamingPlayer.swift | Services/ | AVPlayer-based streaming (separate from AVAudioEngine) | | KeychainService.swift | Services/ | Keychain wrapper for API key storage | | CloudBrowserView.swift | Views/ | Browse categories → albums → tracks with play/add-to-playlist | ### Modified Files (6) | File | Changes | |------|---------| | Track.swift | Add `isCloud`, `cloudStreamPath`, `cloudTrackId` + `fromCloud()` factory | | PlayerViewModel.swift | Add StreamingPlayer, dual-source routing, cloud transport | | SettingsView.swift | Add "Chad Music" section (URL, API key, test connection) | | ContentView.swift | Add cloud browser sheet trigger | | MiniPlayerView.swift | Buffering indicator, cloud icon | | MixBoardApp.swift | Bump DB reset to dbResetV7 | ### How It Works 1. User enters server URL + API key in Settings → Chad Music 2. CloudBrowserView fetches categories/albums/tracks from the API 3. Tapping a cloud track → PlayerViewModel routes to StreamingPlayer (AVPlayer) 4. "Add to Playlist" creates a Track with `isCloud=true` in SwiftData 5. Playing a cloud Track from a playlist → PlayerViewModel detects `isCloud`, builds stream URL, uses StreamingPlayer 6. All transport controls (play/pause/seek/skip/next/prev) route based on `isCloudPlayback` flag ### Navigation Pattern CloudBrowserView is presented as a **sheet** from a toolbar button in PlaylistListView — consistent with the existing Library/Settings sheet pattern. ### DB Migration Nuclear reset approach (existing pattern): bump `dbResetV6` → `dbResetV7` to force schema recreation with new Track fields.