Jellytone
A native iPhone and iPad music player for a self-hosted Jellyfin library, with cache-first browsing, a single playback queue, and verified downloads for local listening.
Jellytone is a native iOS music player for people who keep their music on a Jellyfin server. I built it around a focused flow: connect to one server, browse the library, and listen on iPhone or iPad without having to work through a video-first interface.
The app includes Home, Library, and Search, with albums, artists, songs, playlists, genres, favourites, and downloads. A persistent mini-player opens into Now Playing, with an editable queue, shuffle, repeat, and line-level lyrics when the server provides them. Playback continues in the background, with controls on the Lock Screen and in Control Centre.
Under the SwiftUI interface, the architecture separates presentation, domain models, Jellyfin networking, local storage, and playback. A hand-written URLSession gateway keeps server response types out of the rest of the app, while GRDB provides a SQLite-backed library cache. Screens can show previously loaded content before the network responds, making browsing less dependent on a fast connection to the server.
One playback controller owns both the queue and the AVPlayer lifecycle. That gives the in-app player and system media controls a shared source of truth, rather than letting each surface maintain its own playback state.
Downloads use a manifest to track verified local copies. Playback prefers the local file when verification passes, so a file being present on disk is not enough to treat it as a usable download. Server access tokens stay in the Keychain, TLS validation remains enabled, and connecting over plain HTTP requires explicit confirmation.
The project is open source under the MIT licence and runs on iOS 18.4 or later. It is available to build from source; there is no App Store release yet. The current scope is music playback for a single Jellyfin server, with widgets and CarPlay left for later work.