A modern, privacy-focused RSS reader for iOS with AI-powered content summarization.
- 📰 RSS Feed Management - Subscribe to your favorite RSS feeds with OPML import/export support
- 🤖 AI-Powered Summaries - Intelligent article summarization using Apple Intelligence (iOS 26+) with graceful fallback to NaturalLanguage framework
- 🎧 Podcast Support - Stream podcast episodes with chapter navigation, artwork, and Control Center integration
- 🎙️ Text-to-Speech Audio Player - Listen to articles with full playback controls, variable speed (0.5x-2x), and background playback support
- 🗣️ Voice Selection - Choose from high-quality voices in your language with preview functionality
- 🔒 Lock Screen Integration - Rich Now Playing controls with article thumbnails and accurate duration estimates
- 🔄 Background Sync - Automatic feed updates with hourly background refresh
- 📅 Day-Based Navigation - Browse articles by Today, Yesterday, and older with infinite scroll
- 🔍 Smart Filtering - Filter by category, search articles, and mark as read/unread
- ⭐ Favorites - Save important articles for later
- 🎨 Typography - WordPress-style smart quotes and em/en dashes for beautiful text rendering
- 🔴 Reddit RSS Support - Native Reddit integration with JSON API, animated GIF/video playback, gallery images with zoom/pan, comments view, and author display
- 🌐 Multi-Language Support - Full app localization in English, German, Spanish, and Japanese
- 🌓 Dark Mode Support - Automatic light/dark theme with manual override
- 🎨 Customizable Accent Colors - Choose from 6 vibrant color options
- 📖 Font Options - Select between serif (New York/Georgia) and sans-serif (SF Pro)
- 📱 Pull to Refresh - Quickly sync your feeds
- 🔗 Flexible Reading - Read in-app with Safari View Controller or open in external browser
- 📤 Easy Sharing - Share articles via iOS share sheet
- 🔒 Privacy-First - All data stored locally with SwiftData
- 📱 No Account Required - No sign-up, no tracking, no cloud sync
- 💾 OPML Support - Import/export your feed subscriptions
- 🗑️ Data Portability - Export your data anytime
- iOS 18.0 or later
- iPhone or iPad
- Xcode 16.0+ (for development)
Today is available for free on the App Store for iOS 18.0 and later.
- Clone the repository:
git clone https://github.com/jakespurlock/today.git
cd today/Today- Open the project in Xcode:
open Today.xcodeproj-
Select your development team in the project settings under "Signing & Capabilities"
-
Build and run (⌘R)
Today is built using modern iOS development practices:
- SwiftUI - Declarative UI framework
- SwiftData - Persistence layer for feeds and articles
- Swift Concurrency - Async/await for networking and background tasks
- Apple Intelligence - On-device LLM for article summaries (iOS 26+)
- Background Tasks - BGAppRefreshTask for automatic feed syncing
- Safari View Controller - In-app web browsing
Today/
├── Models/ # SwiftData models (Feed, Article)
├── Views/ # SwiftUI views
├── Services/ # Business logic (RSS parsing, AI, background sync)
├── Utilities/ # Helper utilities (Texturizer)
└���─ Resources/ # Assets and configuration
For detailed architecture documentation, see CLAUDE.md.
# Run all tests
xcodebuild test -project Today.xcodeproj -scheme Today \
-destination 'platform=iOS Simulator,name=iPhone 17 Pro'
# Run specific test suite
xcodebuild test -project Today.xcodeproj -scheme Today \
-destination 'platform=iOS Simulator,name=iPhone 17 Pro' \
-only-testing:TodayTests/TexturizerTests# Debug build
xcodebuild -project Today.xcodeproj -scheme Today \
-configuration Debug build
# Release build
xcodebuild -project Today.xcodeproj -scheme Today \
-configuration Release buildFor detailed release instructions, see RELEASE_PROCESS.md.
Quick version bump:
# Update marketing version
xcrun agvtool new-marketing-version 1.4.0
# Increment build number
xcrun agvtool next-version -all
# Note: agvtool may only update Info.plist
# Verify and update project.pbxproj manually if needed:
grep "MARKETING_VERSION = " Today.xcodeproj/project.pbxprojContributions are welcome! Please feel free to submit a Pull Request.
- Follow Swift API Design Guidelines
- Write tests for new features
- Update documentation for significant changes
- Ensure all tests pass before submitting PR
- Use meaningful commit messages
Be respectful, inclusive, and constructive in all interactions.
This project uses a dual-license structure:
The majority of this project is licensed under the MIT License.
Copyright (c) 2025 Jake Spurlock
See LICENSE for full details.
The file Today/Utilities/Texturizer.swift is licensed under the GNU General Public License v2 or later, as it is derived from WordPress's wptexturize() function.
This component is clearly marked with GPL licensing in its header comments and is isolated from the rest of the application to maintain license clarity.
The Texturizer component is a port of WordPress's text beautification functionality, which is GPL-licensed. To respect WordPress's license while keeping the rest of the app under MIT, we use this dual-license structure.
Jake Spurlock
- Website: jakespurlock.com
- GitHub: @jakespurlock
- Twitter: @whyisjake
- WordPress - Texturizer is derived from the
wptexturize()function in WordPress core - Apple - SwiftUI, SwiftData, and Apple Intelligence frameworks
- RSS Community - For keeping web syndication alive
- iPad-optimized layout with sidebar navigation
- Article content extraction (reader mode)
- Podcast support ✅ (v1.9.0)
- iCloud sync (optional)
- Home Screen widgets
- Siri shortcuts
- Feed discovery from websites
- macOS companion app
- Watch app for reading queue
- Custom notification rules
- Article annotations and highlights
Please report issues on GitHub Issues.
Open a discussion or create a feature request issue.
- CLAUDE.md - Project overview and architecture
- RELEASE_PROCESS.md - Release and deployment guide
- PROJECT_SUMMARY.md - Detailed feature documentation
Today respects your privacy:
- ✅ All data stored locally on your device
- ✅ No analytics or tracking
- ✅ No ads
- ✅ No account creation required
- ✅ No data sent to external servers (except when fetching RSS feeds)
- ✅ AI processing happens on-device (when using Apple Intelligence)
Performance & Sync Reliability
- 🧵 Sync no longer blocks the UI - Article insertion, feed parsing and OPML sync all ran on the main thread; they now run off it
- ⚡️ Launch scales with the window, not the library - Article queries are bounded rather than loading everything ever synced; list state derives in one pass instead of six
- 🔀 One slow feed no longer stalls the rest - Bounded continuous concurrency plus a 15s request timeout, replacing sequential batches and URLSession's 60s default
- 🔎 Search is visible again - The Today search field was collapsed behind a pull gesture that pull-to-refresh usually won
- 🐛 Fixed: OPML feeds silently deactivating - Feed URLs were compared as the OPML listed them rather than as stored, so http-listed feeds were deactivated every sync and stopped updating. Affected feeds reactivate automatically
- 🐛 Fixed: failed syncs blocked retries - A sync where every feed failed recorded itself as successful and refused to retry for two hours
- 🐛 Fixed: temporary redirects - A 302 could permanently overwrite a stored feed URL; only 301/308 do now
- 🧪 Test suite 145 → 277, including the first end-to-end sync tests
⚠️ New database indexes apply to fresh installations only; existing stores stay unindexed until a versioned migration lands
OPML Subscriptions & macOS Polish
- 📥 Remote OPML subscriptions - Subscribe to an OPML URL and keep the feed list in sync automatically
- ☁️ RSS Cloud element parsing
- 🖥️ macOS improvements - Feed management UI, sorted categories, keyboard navigation, gallery fixes, toolbar consistency
- 🔴 Reddit - OP comment highlighting, fullscreen gallery on iPad, flattened comment fixes
- 🐛 Fixed OPML duplicate feed creation, macOS crashes in feed management, and article text width on iOS
- 🚀 Faster cold launch - Moved sync orchestration and article insertion off the launch critical path
- 🐛 Fixed a crash when an article has no link
Podcast Support
- 🎧 Native Podcast Playback - Stream and play podcast episodes directly in-app
- 🎵 Full Now Playing View - Beautiful full-screen player with artwork, progress, and controls
- 📑 Chapter Support - ID3 chapter extraction with tap-to-navigate functionality
- 🖼️ Chapter Artwork - Display episode and chapter-specific artwork
- 🎛️ Control Center Integration - Lock Screen and Control Center playback controls
- ⏩ Speed Control - Adjustable playback speed from 0.5x to 2x
- 🏷️ Podcasts Category - New "Podcasts" filter in Today view to browse all episodes
- 🔊 Waveform Indicator - Visual indicator for podcast episodes in article lists
- 🔄 Background Playback - Continue listening with screen off or app backgrounded
- 📥 OPML Import Fixes - Improved compatibility with NetNewsWire, Feedflow, Stream, and Feeder
- 🐛 Bug Fixes:
- Fixed timezone abbreviation parsing (EDT, PST, etc.)
- Fixed race condition in chapter prefetching
- Added safety checks for large/corrupted ID3 tags
Reddit Improvements & Content Filtering
- 🔴 Consolidated Reddit Views - Unified post and comment viewing for streamlined experience
- 🤖 AutoModerator Filtering - Automatically hide AutoModerator and deleted comments
- 📺 Fullscreen Video Playback - Reddit embedded videos now support fullscreen mode
- 🔤 HTML Entity Decoding - Proper display of special characters (&, <, >, etc.) in all content
- 🎯 Discrete Content Filtering - New system for filtering unwanted content
- 🐛 Bug Fixes:
- Fixed HTML entities (
&,<, etc.) displaying in article titles - Fixed Reddit posts in AI summaries opening in wrong view
- Fixed video/GIF playback interrupting background audio
- Fixed HTML entities (
- 🛠️ Code Quality - Removed 381 lines of duplicate code for better maintainability
Brand Refresh
- 🎨 New App Icon - Fresh, modern icon with International Orange branding
- 📱 Simplified App Name - Clean "Today" display name on home screen
- ✨ Polish & Refinement - Enhanced visual identity and user experience
Text-to-Speech Audio Player & Voice Enhancements
- 🎙️ Text-to-Speech Audio Player - Listen to articles with full-featured audio playback
- ⏯️ Playback Controls - Play, pause, stop, and seek through articles with progress slider
- 🎚️ Variable Speed - Adjustable playback speed from 0.5x to 2x
- 📱 Mini Player - Persistent audio controls across all tabs
- 🔇 Background Playback - Continue listening with screen off
- 🔒 Lock Screen Controls - Full Now Playing integration with article thumbnails
- 🗣️ Voice Selection - Choose from high-quality voices with live preview
- 🌐 Smart Filtering - Only shows voices for your device language
- 🎯 Voice Quality - Enhanced and Premium voice indicators
- 🖼️ Article Artwork - Shows article thumbnails on lock screen with intelligent caching
- ⏱️ Accurate Duration - Real-time estimates based on word count
- 🌍 Complete Localization - All audio features translated to German, Spanish, and Japanese
- 🔄 Background Sync Improvements - More reliable feed updates with persistent tracking
- ⭐ App Store Review System - Respectful review prompts based on usage
Multi-Language Support
- 🌐 Complete Spanish localization - Full app translation including AI features
- 🌐 Complete German localization - Full app translation including AI features
- 🌐 Complete Japanese localization - Full app translation including AI features
- 🎨 Localized Settings - Theme and Font options translated
- 🗣️ Community Credit - Special thanks to u/kikher for the multi-language suggestion
Reddit RSS Support
- 🔴 Native Reddit integration - Add subreddits as feeds using simple names (e.g., "technology")
- 🎬 Animated GIF/video playback - Reddit posts with animated content play automatically
- 🖼️ Gallery support - Swipe through multi-image posts with pinch-to-zoom and pan gestures
- 💬 Comments view - Read Reddit comments directly in the app with proper threading
- 👤 Author display - See post authors in list view instead of feed names
- 📰 Newsletter integration - Reddit posts work seamlessly in AI-generated newsletters
- 🎯 Simplified feed picker - Choose between RSS Feed or Reddit when adding new feeds
- 🔄 Previous/Next navigation - Navigate between Reddit posts and articles
Feed Navigation & Category Improvements
- 🎯 Tap feed to view articles - New feed article view with unread filtering
- 📊 Unread count badges on feed list items
- 🔄 Swipe/long-press for settings - Access edit/delete via swipe or context menu
- 📂 Smart category filters - Hide empty categories, show only categories with articles
- 🔤 Title-case categories - Consistent capitalization (General, Work, Tech, etc.)
- 🔄 One-time migration - Automatically updates existing feeds to title-case
- 🎨 Preserved custom categories - Your custom category names stay exactly as set
- 🐛 Bug fix: Category capitalization inconsistencies (thanks @desrosj)
Official App Store Launch
- 🚀 Public release on App Store
- 🔧 Fixed iOS deployment target (18.0+ for wide compatibility)
- 🤖 Apple Intelligence properly available on iOS 26+ devices
- 🐛 Resolved availability checks for stored properties
- 📢 Marketing launch across social platforms
- 🎉 Apple Intelligence integration for smart summaries
- 📅 Day-based article navigation (Today/Yesterday/Older)
- 📖 Improved article detail toolbar with context menu
- 📤 Share button in article detail
- 🎨 Dynamic version display in Settings
- ✨ Smart quotes and typography improvements
- 🐛 Bug fixes and performance improvements
- 🎨 Serif/sans-serif font preference
- 🎨 Customizable accent colors
- 🐛 Initial bug fixes
- 🎉 Initial release
- 📰 RSS feed management
- 🤖 AI summaries (NaturalLanguage)
- 🔄 Background sync
- 🌓 Dark mode support
- 📱 OPML import/export
Made with