FRadioPlayer 0.3.0 is the largest update since the observer migration: modernized internals, a real recovery story for bad networks, and the library's first test suite.
Highlights
- Stall recovery, rebuilt: mid-play stalls are now detected via
AVPlayer.timeControlStatusand recovered with a bounded retry ladder (reload with backoff). If the stream does not come back, playback ends in a clean stopped + error state instead of loading forever. - Stopping actually stops: stop during loading sticks, fatal stream errors stop playback so play buttons stay truthful, and pressing play after an error rebuilds the pipeline from the URL (failed player items are terminal and are no longer reused).
- NWPathMonitor replaces the vendored Reachability (316 fewer lines, no force-unwrap, modern network signals).
- iOS 14 support restored, with modernized macOS 11+ and tvOS 14+ floors.
Fixed
- Duplicate
itemDidChangenotifications when switching stations, repeatedartworkDidChange(nil), and a spurious.pausedstate on idle URL changes - Cannot stop radio while loading (#12)
- Player kept playing after the stream died or the server was interrupted (#61, #63)
- Stuck in loading after
isPlaybackBufferEmpty(#75) - Loading state now stays in sync with the player when resuming a stopped stream
Testing
- New suite of 33 tests: public API contract lock, metadata extractor characterization, artwork API with stubbed networking, playback fixtures, stall recovery, and state machine regressions
- CI runs the full suite on every push and pull request
Demo app
- Lock screen falls back to the station artwork when track art is unavailable
- Live streams show a stop button on the lock screen instead of pause
Requirements
iOS 14+, macOS 11+, tvOS 14+, Swift 5.9+ / Xcode 15+.
Note for SPM consumers: pre-1.0 minor versions do not flow automatically. Update your dependency rule to receive this release:
.package(url: "https://github.com/fethica/FRadioPlayer.git", from: "0.3.0")Full Changelog: 0.2.3...0.3.0