Minimalist local music player for iOS, iPadOS, and macOS.
What was needed to get Flackbird ready for review, and why. Kept in the repo so the reasoning survives, and because most of it applies to any small, free, offline app.
For the iOS version, paste this into the “Notes” field of App Review Information in App Store Connect (it fits the 4,000-character limit), and attach the screen recording there too. It exists because the app ships with no music: without instructions a reviewer opens it, sees an empty library, and has nothing to test. Apple also asks first-time developers for a description of the app, its external services, regional differences, and any third-party material, plus a screen recording on a physical device starting from launch; those answers are folded in here so later submissions carry them.
PURPOSE AND AUDIENCE Flackbird is an offline music player for music files people already own, such as FLAC files bought from download stores or ripped from CDs. It is for listeners who keep their own music library, especially lossless audio, and want to play it without a streaming subscription, account, or internet connection. It turns a folder of files into a browsable library of playlists, albums, and artists using the files’ own tags and cover art, and shows the audio quality of each file.
SETUP (about 30 seconds, no login) The app ships with no music, so one audio file is needed:
- In Safari, open https://krisfur.github.io/flackbird/sample.flac
- Tap the download, then “Save to Files”.
- Choose On My iPhone (or On My iPad) > Flackbird, and tap Save.
- Open Flackbird. The track appears under All Tracks and Albums. Tap it to play. Alternatively, drag any .flac, .mp3, .m4a, .wav, or .aiff file into the Flackbird folder under Files sharing in Finder.
MAIN FEATURES Browse by Folders, Albums, Artists, and All Tracks; search; tap a track to play; open the full player from the bar at the bottom for seeking, shuffle, repeat, and the audio quality line; lock screen and Control Center controls; Settings (gear icon) for folder choice and appearance. Siri and Shortcuts: requests such as “Shuffle my library in Flackbird” or “Play <folder, album, or artist> in Flackbird” play music, and the same actions appear in the Shortcuts app. Siri must first be turned on for Flackbird: Settings (gear icon) > Siri & Shortcuts opens Flackbird’s page in the Shortcuts app; tap the (i) button at the top right and turn on Siri.
RECORDING The attached recording was made on a physical iPhone running the latest iOS. The music shown is my own personal library, copied onto the device through the Files app; the app itself provides no content. Lock screen controls are supported but can’t be captured, as screen recording stops when the device locks.
EXTERNAL SERVICES None. No servers, SDKs, authentication, payments, analytics, or AI services, and no network connections. Only Apple frameworks (SwiftUI, AVFoundation, MediaPlayer, App Intents) running on the device.
REGIONAL DIFFERENCES None. The app works identically in all regions. It is not offered in China mainland.
REGULATED INDUSTRY OR THIRD-PARTY MATERIAL Not applicable. No regulated industry, and no third-party content: the app ships no music and plays only files the user provides. The sample track and App Store screenshot content are generated by me.
OTHER NOTES
- No account, login, purchases, or subscriptions. Everything is free.
- No permission prompts. The app reads only files in its own folder or a folder the user picks.
- Background audio keeps playback going when the screen locks.
- The only web link is the GitHub link in Settings, which opens Safari.
For the macOS version, use these instead, with a recording made on a Mac. They swap the iPhone setup for choosing a folder, and describe the Mac controls.
PURPOSE AND AUDIENCE Flackbird is an offline music player for music files people already own, such as FLAC files bought from download stores or ripped from CDs. It is for listeners who keep their own music library, especially lossless audio, and want to play it without a streaming subscription, account, or internet connection. It turns a folder of files into a browsable library of playlists, albums, and artists using the files’ own tags and cover art, and shows the audio quality of each file.
SETUP (about 30 seconds, no login) The app ships with no music, so one audio file is needed:
- In Safari, open https://krisfur.github.io/flackbird/sample.flac (it saves to Downloads).
- Open Flackbird, click the gear icon (Settings) at the top right of the window, then Choose Folder…, and pick Downloads.
- The track appears under All Tracks and Albums. Click it to play. Any folder of .flac, .mp3, .m4a, .wav, or .aiff files works the same way; each subfolder becomes a playlist. The app remembers the chosen folder through a security-scoped bookmark.
MAIN FEATURES Browse by Folders, Albums, Artists, and All Tracks in the sidebar; search; click a track to play. The bar at the bottom of the window controls playback; click it to open the full player (seeking, shuffle, repeat, and the audio quality line). The Space bar plays and pauses, and the Playback menu has Play/Pause, Next (Command-Right Arrow), and Previous (Command-Left Arrow). Media keys and Now Playing in Control Center work as with other players. Settings (gear icon) has folder choice and appearance. Siri and Shortcuts: requests such as “Shuffle my library in Flackbird” or “Play <folder, album, or artist> in Flackbird” play music, and the same actions appear in the Shortcuts app. As with any app’s shortcuts, Siri must first be turned on for Flackbird in the Shortcuts app.
RECORDING The attached recording was made on a Mac running the latest macOS, starting from launching the app. The music shown is my own personal library of purchased and ripped files; the app itself provides no content.
EXTERNAL SERVICES None. No servers, SDKs, authentication, payments, analytics, or AI services, and no network connections. Only Apple frameworks (SwiftUI, AVFoundation, MediaPlayer, App Intents) running on the device.
REGIONAL DIFFERENCES None. The app works identically in all regions. It is not offered in China mainland.
REGULATED INDUSTRY OR THIRD-PARTY MATERIAL Not applicable. No regulated industry, and no third-party content: the app ships no music and plays only files the user provides. The sample track and App Store screenshot content are generated by me.
OTHER NOTES
- No account, login, purchases, or subscriptions. Everything is free.
- The app is sandboxed and reads only the folder the user picks. No permission prompts beyond the standard folder picker.
- The only web link is the GitHub link in Settings, which opens in the browser.
sample.flac is served from this site rather than bundled in the app, so it costs users nothing in download size while still giving a reviewer something to play in one step.
It is generated, not sourced from a music library: make-sample.sh builds it from sample-tone.py (a C major arpeggio, stdlib Python) and sample-cover.swift (white text on black, CoreGraphics). Nothing in it belongs to anyone else, so there is no licence to honour and no attribution to carry. The short music FLACs on Wikimedia Commons are CC-BY, which would have meant an attribution notice in perpetuity for a throwaway demo file.
The file is about 94 KB: a 5 second mono tone plus a 600x600 cover. The cover matters more than it looks: it means the reviewer sees the tag parser read a real embedded picture rather than the placeholder artwork.
Privacy manifest. SwiftFlac/PrivacyInfo.xcprivacy declares NSPrivacyAccessedAPICategoryUserDefaults with reason CA92.1. Since May 2024 App Store Connect rejects uploads that use a required-reason API without declaring it, with ITMS-91053, before review even begins. UserDefaults is the only such API the app touches. File timestamps are deliberately avoided, including in the library change detection, to keep it that way.
Export compliance. ITSAppUsesNonExemptEncryption is set to false in Support/Info.plist. Without it, App Store Connect asks the export question on every single submission.
Code signing. CODE_SIGN_IDENTITY for macOS was pinned to - (ad-hoc) in both build configurations, which overrides automatic signing and cannot produce a distributable archive. It is now Debug only, so local builds still need no provisioning profile.
Accessibility. The transport, shuffle, repeat, and search-clear controls are icon-only, so VoiceOver announced the SF Symbol name. They now carry labels, with shuffle and repeat exposing their state as an accessibility value rather than folding it into the label.
App name. The app was first submitted as SwiftFlac and rejected under guideline 5.2.5 (Intellectual Property): “Swift” is an Apple trademark. It was renamed Flackbird, keeping the bundle ID (com.kfurman.swiftflacplayer), the repository, and the Xcode project and module names, none of which users see. The sample track’s tags were regenerated with the new name, since reviewers see them in the app.
Privacy policy. Required for every app in App Store Connect, including apps that collect nothing. Served from this site at privacy, so the published text lives with the code and cannot drift from it. It covers the one on-device sharing there is: folder, album, and artist names given to the system for Siri and Shortcuts.
Siri and Shortcuts. Built with App Intents, which need no entitlement and show no permission prompt. Siri phrases only work once the user turns on Siri for the app in the Shortcuts app, and apps cannot do that themselves, so the review notes walk through it and Settings links straight there.
Library refresh. Not a store requirement, but it was the real reason the app looked untestable. The library only scanned at launch, so music added while the app sat in the background stayed invisible until a relaunch or a manual rescan, which reads as a broken app. It now rescans when the app returns to the foreground, gated behind a cheap fingerprint of the file tree so an unchanged library costs a directory walk instead of reopening every file.
screenshots/ are App Store sizes (ios-* for the 6.9-inch iPhone, ipad-* for the 13-inch iPad, mac-* for Mac), generated from a demo library by take_screenshots.sh.