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

4.5 KiB

BearWave for macOS

Native macOS 26 port of the Linux/KDE app BearWave.

This repository is the current SwiftUI + AVFoundation version built as a SwiftPM app. The product scope is focused internet radio on macOS.

Current Scope

  • Radio Browser integration for Top, Germany, Netherlands, World, search, favorites, recents, and manual stations
  • Native SwiftUI macOS UI with sidebar, list, detail panel, player bar, settings, and menu bar extra
  • Station folders for organizing favorites and saved stations
  • Stream playback through AVPlayer
  • Playback states: connecting, buffering, playing, paused, stopped, failed
  • Stream metadata display via AVPlayerItemMetadataOutput
  • Station favicons/artwork with local disk cache
  • Now Playing artwork resolution with fallback chain: metadata lookup, station favicon, app default artwork
  • Mini Player with Cmd+M

Project Layout

  • Package.swift SwiftPM package with:
    • BearWaveCore shared app logic and resources
    • BearWave app executable
    • BearWaveChecks lightweight verification executable
  • Sources/BearWaveApp App entrypoint and scene setup
  • Sources/BearWaveCore App logic split into:
    • App/ high-level app coordinator (AppModel.swift)
    • Models/ domain models (RadioStation, StationGroup, PlaybackStatus, PlaybackError, StationPage)
    • Services/ Radio Browser client, playback controller, artwork loading, Now Playing artwork resolution
    • Stores/ persistence, settings, station library
    • Views/ SwiftUI UI (sidebar, list, detail, player bar, settings, menu bar, mini player)
    • Support/ resource helpers
    • Resources/ localized strings, assets, entitlements placeholder
  • Tests/BearWaveChecks Executable smoke checks for decoding, search normalization, filtering, and library behavior
  • script/build_and_run.sh Local build, bundle, and launch entrypoint

Build and Run

./script/build_and_run.sh

Useful modes:

./script/build_and_run.sh --verify
./script/build_and_run.sh --debug
./script/build_and_run.sh --logs
./script/build_and_run.sh --telemetry

Development Notes

  • Target platform is macOS 26
  • Preferred workspace is: /Users/sebastian/Development/radioappmac
  • Build with: swift build --disable-index-store
  • Lightweight verification: CLANG_MODULE_CACHE_PATH=/private/tmp/bearwave-clang-cache swift run --disable-index-store BearWaveChecks
  • The generated app bundle lives in: ./dist/BearWave.app
  • The run script stages SwiftPM resource bundles and localization directories manually into the app bundle

Playback and Metadata Notes

  • Audio playback uses AVPlayer
  • Stream metadata is read through AVPlayerItemMetadataOutput
  • PlaybackController exposes explicit playback states instead of a simple play/pause boolean
  • Some radio streams provide current-song metadata; many do not
  • MediaPlayer is imported with @preconcurrency because the app updates MPNowPlayingInfoCenter
  • MPMediaItemArtwork is created from a stable CGImage request handler
  • ATS is explicitly opened for media and http:// streams in the generated app Info.plist, otherwise many radio streams do not play

Persistence

Data is stored under native macOS locations:

  • Application Support/BearWave/

    • favorites.json
    • manual-stations.json
    • groups.json
    • state.json
  • Caches/BearWave/

    • api_cache/
    • artwork cache files

The app also tries to import old Linux-style files on first run if present:

  • ~/.config/bearwave/favorites.json
  • ~/.config/bearwave/state.json

Current UX Behavior

  • Search is global against Radio Browser and independent from the current browse page
  • Search results appear on a dedicated Search Results page
  • Search ranking intentionally filters naive mid-word matches such as slam matching Islamabad
  • A right-side detail panel shows station metadata and current stream metadata when available
  • German localization is active across the app

Known Technical Edges

  • The app is currently a SwiftPM-staged .app, not an Xcode-managed release app
  • Debug signing and sandbox behavior are intentionally pragmatic, not release-ready
  • Resource handling is functional but still tied to the custom staging script

Suggested Next Work

  • Improve packaging, signing, and notarization
  • Add more targeted playback diagnostics per stream failure mode
  • Expand tests around playback-state transitions and search ranking
  • Add cache eviction for memory and disk caches
  • Keep station folders lightweight and radio-focused