- Swift 98.9%
- Python 1.1%
* YouTube account sign-in via the TV device-code flow (SmartTube audit), 0.1.14 Audit (AUDIT.md 0.1.14 addendum): SmartTube/MediaServiceCore are MIT; sign-in is the OAuth 2.0 device-code flow of YouTube's own TV app. No hardcoded client and no Google Cloud project: the TV client id and secret are extracted at runtime from the youtube.com/tv base script (ClientData.java patterns), tokens come from youtube.com/o/oauth2 (scope gdata.youtube.com + youtube-paid-content), only the refresh token persists, and signed browse runs as the TVHTML5 client (FEsubscriptions / default). Live-verified end-to-end 2026-10-26 before implementing. Implemented fresh in Swift: YouTubeTVAuth (extraction, device flow, refresh, TV browse), refresh token in Keychain, Settings sign-in sheet with spoken code + polling, Subscriptions and Recommendations sources in Discover, browse parsing extended to gridVideoRenderer. Tests: extraction, user code, token outcomes, grid browse parsing. * Tests: fix brace mismatch in grid browse fixture JSON * Tests: pad grid fixture past Swift multiline indentation stripping |
||
|---|---|---|
| .github/workflows | ||
| BlindRSS | ||
| BlindRSS.xcodeproj | ||
| BlindRSSTests | ||
| docs | ||
| tools | ||
| .gitignore | ||
| AGENTS.md | ||
| AUDIT.md | ||
| CHANGELOG.md | ||
| LICENSE | ||
| README.md | ||
BlindRSS for iOS
Native SwiftUI port of BlindRSS, the screen-reader-first desktop RSS and podcast client. Built for VoiceOver first, following ios-swiftui-accessibility-techniques by CVS Health.
Current release: 0.1.12. The 0.1.12 release closes the feature gap with the desktop app (v2.5.x): everything portable to iOS is now here.
Install with AltStore
BlindRSS is in the serrebiALT source.
-
In AltStore, open Sources, tap Add, and paste:
https://raw.githubusercontent.com/serrebidev/serrebiALT/main/apps.json
-
Find BlindRSS in the source and install it. AltStore re-signs the app with your account, so no developer certificate is needed.
You can also download the .ipa directly from Releases and install it with AltStore, SideStore, or another sideloader.
What works
- RSS, Atom, and JSON Feed subscriptions, grouped by category, stored on device with SwiftData.
- All, Unread, Read, and Favorites views. Mark read and unread, mark all read, favorites, search, and delete with restore snapshots.
- Per-feed error tracking with a Feeds with Errors view.
- OPML import and export.
- Podcasting fully supported, matching the desktop player: enclosure streaming and downloads, Podcasting 2.0 chapters from feeds, resume playback, persistent auto-advancing play queue, lock-screen controls, background audio, volume, speed presets, sleep timer, auto-download, one combined Search Feeds and Podcasts (Apple Podcasts and gPodder by name, feed detection for pasted URLs), and Wayback archive recovery with batch download.
- Feed refresh with VoiceOver announcements of new article counts.
Also included: hosted providers (Miniflux, plus Inoreader, The Old Reader, and BazQux over the Google Reader API) in Settings, Online Account; Smart Folders; Filter Rules with the desktop's full action set (mark read, favorite, delete, do not notify, move to a category, label, stop) applied as a pipeline as articles arrive; a Deleted Articles view with restore; feed properties editing with per-feed notification mute, the feed's published description, and Reset Title; full-text recovery; feed discovery from web page URLs; media downloads; a ten-band equalizer with the desktop presets and silence skipping for streamed and downloaded episodes; YouTube articles with an embedded player, description chapters, and a readable transcript; AirPlay; and notifications for new articles.
New in 0.1.12 (desktop parity): discovery across every keyless desktop directory (fyyd, Podverse, Feedly, NewsBlur, Reddit, Lemmy, Mastodon, Bluesky, PieFed, Groups.io, Feedspot, Google News, Bing News) grouped by source; social page URLs resolve to feeds when subscribing (Mastodon, Bluesky, Reddit, Lemmy, Groups.io, GitHub, YouTube channels and playlists); YouTube Takeout ZIP import; Persistent Searches in the feed list; browsable Categories with rename and delete; article retention; delete behaviour (Deleted Articles, permanent, or move to a category) with an optional confirmation; reader presentation options (bullets, quote markers, link targets, image alt text) and a search-scope setting; last-view restoration at launch; a built-in User Guide; Open Article by URL and Open Media URL; and Site Cookies import.
Not ported: Chromecast and DLNA casting (needs Google's Cast SDK and a Cast application id), direct YouTube stream extraction and stream-resolved features (no yt-dlp on iOS; videos play in the embedded player), and translations (desktop gettext catalogs need converting to String Catalogs). See AUDIT.md.
VoiceOver
Every touch swipe action is duplicated as a VoiceOver action on the same row. Articles offer Open in Browser, Download Media, Copy Link, Read, Mark Read or Unread, Favorite, Play, Add to Play Queue, Share, and Delete, in an order you can change in Settings, Article Actions. Feeds offer Open, Refresh, Mark All Read, and Delete.
The full gesture guide is in docs/VOICEOVER.md. The short version:
- Swipe right and left to move. Each article speaks title, feed, date, read state, favorite state, and "has audio" once.
- Swipe up or down on an article or feed to cycle its actions, then double tap.
- Two-finger rotate for the rotor: Headings, Unread, Favorites, With Audio, and Chapters.
- Magic Tap, a two-finger double tap, plays or pauses anywhere.
- In the player, focus Progress or Playback speed and swipe up or down to adjust.
Documentation
- AUDIT.md — desktop audit, data model map, feature inventory, port plan, VoiceOver design rules, and open decisions.
- docs/VOICEOVER.md — complete VoiceOver gesture guide.
- CHANGELOG.md — release notes by version.
- docs/CPU-AUDIT.md — CPU audit of Miniflux sync, refresh, and adding feeds, with the 0.1.1 fixes.
Build (Mac required)
CI builds and releases the app. To build locally:
- Open
BlindRSS.xcodeprojin Xcode 16 or later. - Run on a device or simulator (iOS 17 or later). Unsigned CI builds are produced with
CODE_SIGNING_ALLOWED=NO; AltStore re-signs on install.
Run the accessibility checker from the techniques repo against the sources:
brew tap cvs-health/ios-swiftui-accessibility-techniques https://github.com/cvs-health/ios-swiftui-accessibility-techniques.git
brew install --HEAD cvs-health/ios-swiftui-accessibility-techniques/a11y-check
a11y-check BlindRSS
CI runs the same check on every push and attaches the report to the build artifacts. Unit tests cover the feed parsers, HTML text, and OPML. Run them with Command-U on a Mac, or in CI.
Layout
BlindRSS/Models— SwiftData models mirroring the desktoprss.dbschema.BlindRSS/Services— feed parsing (RSS, Atom, JSON Feed), library store, OPML, AVPlayer playback, VoiceOver announcements.BlindRSS/Views— feed list, article list, reader, player, add feed, settings.BlindRSSTests— parser, HTML text, and OPML unit tests..github/workflows/build.yml— tests, accessibility check, unsigned IPA, and tag releases.
License
MIT, same as the desktop app. See LICENSE.