Files
bearwave-mac/ARCHITECTURE.md
2026-06-25 09:21:42 +02:00

6.2 KiB

Architecture

This repository is a native macOS 26 SwiftPM internet radio app.

The app is split into a small app target and a larger shared core target.

Top-Level Structure

  • Package.swift Defines:
    • BearWaveCore
    • BearWave
    • BearWaveChecks
  • Sources/BearWaveApp App entrypoint and scene wiring
  • Sources/BearWaveCore Application logic, models, services, stores, views, and resources

Main Runtime Objects

BearWaveApp

File:

Responsibilities:

  • create the root AppModel
  • host the main WindowGroup
  • host MenuBarExtra
  • host Settings
  • manage window sizing and mini-player mode
  • define app commands such as play/pause and Cmd+M

This file should stay thin. It is scene setup, not business logic.

AppModel

File:

Responsibilities:

  • own the major runtime subsystems
  • coordinate radio, playback, settings, and artwork
  • restore launch state
  • route user actions like play(_:), setVolume(_:), and quit()

Owned objects:

  • SettingsStore
  • StationLibrary
  • PlaybackController
  • StationArtworkLoader
  • NowPlayingArtworkResolver

AppModel is the top-level coordinator. It should not become a dumping ground for unrelated view logic.

Domain Store

StationLibrary

File:

Responsibilities:

  • load and store browse pages
  • manage global search
  • manage favorites
  • manage recents
  • manage manual stations
  • manage station folders
  • persist radio-related state

Important behaviors:

  • search is global, not page-local
  • search results live on a dedicated Search Results page
  • search ranking is stricter than raw Radio Browser substring matching
  • folders are persisted entities and not just transient UI state

Playback and Metadata

PlaybackController

File:

Responsibilities:

  • own the shared AVPlayer
  • manage playback state transitions
  • play radio streams
  • expose explicit playback states
  • read timed metadata through AVPlayerItemMetadataOutput
  • update MPNowPlayingInfoCenter
  • handle artwork updates

Important invariants:

  • do not collapse playback state to only isPlaying
  • metadata handling must tolerate streams that provide nothing useful

Network Services

RadioBrowserClient

File:

Responsibilities:

  • call Radio Browser endpoints
  • decode station payloads
  • provide search support
  • cache API responses on disk

Artwork Services

Files:

Responsibilities:

  • load and cache station favicons
  • resolve playback artwork for Now Playing
  • fall back through available artwork sources when metadata is incomplete

Persistence

PersistenceStore

File:

Responsibilities:

  • JSON persistence for:
    • favorites
    • manual stations
    • groups
    • playback state
  • manage application support and cache directories
  • import legacy Linux config files on first run where applicable

UI Structure

Main views:

High-level behavior:

  • ContentView switches between full app UI and mini-player mode
  • sidebar chooses radio pages and folders
  • station list and station detail cover browse, search, favorites, recents, manual stations, and folders
  • PlayerBarView stays focused on radio playback controls

Data Flow

  1. User selects a page or search query
  2. StationLibrary loads data through RadioBrowserClient
  3. UI renders visible stations
  4. User starts playback
  5. AppModel records playback and forwards to PlaybackController
  6. PlaybackController updates playback state, metadata, artwork, and Now Playing

Build and Packaging Notes

  • The current app bundle is staged by script/build_and_run.sh
  • SwiftPM resource bundles are copied manually into dist/BearWave.app
  • Localization directories are copied manually as part of staging
  • This is good enough for local development but not yet a polished release pipeline

Architectural Guardrails

  • Keep the app native-first for macOS
  • Keep search global and independently modeled
  • Keep explicit playback states
  • Keep BearWaveApp thin
  • Do not move product behavior into ad hoc view code when it belongs in a store or service