Swift Radio v3: Ten years later

The first Swift Radio commit was pushed on September 4, 2015. Ten years, two major versions, and nearly 3,000 GitHub stars later, v3 is here.

The last tagged release was v2.0.8 back in April 2020. In the six years since, the project accumulated 129 commits, and more code was deleted than added. A lot has changed in iOS since then, and this release catches up with all of it.

Swift Radio v3 station list with card-based layout and now playing bar
Swift Radio v3 now playing screen with album art, LIVE badge, and playback controls

Everything looks different

The entire interface has been redesigned:

  • Station list: modern card layout with stronger visual hierarchy, album art front and center
  • Now Playing: full-screen experience with dynamic blur backgrounds, SF Symbol controls, and a scrolling marquee for long track names
  • App icon: new blueprint-style icon that signals "this is a starter project, replace me with your own"

This is not a color swap or a font update. If you used Swift Radio before, you will notice the difference immediately.

Live streams and podcasts, handled differently

One of the most practical changes in v3 is how the app treats different types of audio:

  • Live radio shows a LIVE indicator with stop/play controls, because you cannot pause a live broadcast
  • On-demand streams (podcasts, MP3 files) keep standard pause/resume behavior with a scrubber for seeking
  • Tapping a station that is paused or stopped now resumes it directly. No extra steps

Fewer confusing states, fewer taps to get back to your audio.

Now playing screen for a live station showing the LIVE badge and stop button

Live: LIVE badge + stop

Now playing screen for an on-demand file showing the scrubber and pause button

On-demand: scrubber + pause

Better for developers

All core navigation has moved from storyboards to a coordinator pattern, built entirely in code. The launch screen uses UILaunchScreen in Info.plist instead of a storyboard file. If you are forking Swift Radio for your own project, there are fewer hidden dependencies to untangle.

Networking has been rewritten with async/await, and deprecated APIs have been cleaned up across the board for modern Xcode and iOS toolchains. CarPlay support has been carried forward and tested alongside the main app.

Ready for translation

Every user-facing string now lives in a single Xcode String Catalog (Localizable.xcstrings). Want to ship Swift Radio in French, Arabic, or Japanese? Add a language in Xcode project settings, fill in the translations, and build. No Swift code changes needed.

I wrote a separate guide on this: How to translate Swift Radio into any language.

Libraries that make it work

Two libraries power the core experience.

FRadioPlayer is the audio engine behind Swift Radio. I extracted it from the app back in 2017 and it now has 24 releases and close to 300 stars on its own.

The biggest API change since the last Swift Radio release was replacing the single-delegate pattern with addObserver / removeObserver, so multiple components can listen to playback events independently. I wrote about this in detail in FRadioPlayer 0.2.1: Migrating from delegates to observers.

If you only need audio streaming without the full radio UI, FRadioPlayer is a lightweight option you can drop into any Swift project.

LNPopupController powers the now playing bar and the swipe-up-to-expand interaction, the same pattern you know from Apple Music. Instead of pushing a full-screen player on every tap, the now playing view lives in a popup bar at the bottom of the screen. Tap or swipe up to expand it, swipe down to dismiss. It makes navigating between the station list and the player feel seamless.

What's next

v3 is a foundation reset. The architecture is cleaner, the playback behavior is smarter, and the project is easier to fork and customize than it has ever been.

Next on the roadmap: SwiftUI. The coordinator-based architecture in v3 was a deliberate step in that direction, making the eventual migration incremental rather than a full rewrite.

Star the repo if it is useful, fork it if you want to make it yours.