Skip to content

Repository files navigation

SubFeed

A standalone iOS app that keeps up with your YouTube subscriptions — no Google account required.

SubFeed fetches your subscribed channels via YouTube's public RSS feeds, stores video metadata locally in SwiftData (SQLite), and presents a clean, filterable timeline. Completely standalone: no server, no login, no tracking.

What It Does

  • Subscribe to YouTube channels by handle (@channel), channel ID (UC...), URL, or OPML import
  • Browse a unified latest-videos feed across all your subscriptions
  • Filter by Shorts, watched status, duration, search text
  • Sort by newest, oldest, channel, or video length
  • Inline YouTube video playback with progress tracking (auto-mark watched at 20%)
  • Favorite videos for keeps
  • Mute channels to hide their videos from the main feed
  • Group channels for organisation
  • Export/import backups (JSON) and channel lists (OPML)
  • Optional YouTube Data API key for Shorts verification and channel resolution

Requirements

  • iOS 18.0+
  • Xcode 16.0+
  • Swift 6.0

Developer Quickstart

Use these commands when you want the shortest path from clone to verification:

xcodebuild -list -project SubFeed.xcodeproj
swift build
swift test
xcodebuild -project SubFeed.xcodeproj -scheme SubFeedApp -destination 'platform=iOS Simulator,name=iPhone 16' build
xcodebuild test -project SubFeed.xcodeproj -scheme SubFeedApp -destination 'platform=iOS Simulator,name=iPhone 16'

Architecture

YouTube RSS (feeds/videos.xml?channel_id=UC...)
    │
    ▼
RSSFeedService (actor, URLSession)
    │
    ▼
RSSXMLParser (Foundation XMLParser delegate)
    │  Extracts: yt:videoId, title, published, channelId, duration, thumbnail
    ▼
FeedViewModel.refreshAllFeeds()
    │  Dedup → merge metadata → insert new → SwiftData save
    ▼
SwiftData (StoredVideo, StoredChannel, WatchedVideoEntry, etc.)
    │
    ▼
FeedViewModel.filteredVideos (computed, cached)
    │  Filters: shorts, watched, muted, min duration, search
    │  Sorts: newest, oldest, channel, duration
    ▼
SwiftUI (LatestFeedView, ChannelFeedView, FavoritesView)

Key Components

Layer Files
Models Sources/SubFeed/Models/ — StoredVideo, StoredChannel, AppSettingsModel, WatchedVideoEntry, FavoriteVideoEntry
Services Sources/SubFeed/Services/ — RSSFeedService, RSSXMLParser, ShortVerifier, ChannelResolver, DataRetentionService, BackupArchive, CredentialStore
Views Sources/SubFeedApp/ — LatestFeedView, ChannelFeedView, FavoritesView, SubscriptionsView, SettingsView, AddChannelView, VideoCard, KeywordFiltersSheet

Package Structure

  • SubFeed — shared library (models, services, parsers)
  • SubFeedApp — the iOS app target (SwiftUI views, app delegate)
  • SubFeedTests — Swift Testing tests

Building

Open SubFeed.xcodeproj in Xcode 16+, select the SubFeedApp scheme, and build for an iOS 18 simulator or device.

Or from the command line:

xcodebuild -list -project SubFeed.xcodeproj
xcodebuild -project SubFeed.xcodeproj -scheme SubFeedApp -destination 'platform=iOS Simulator,name=iPhone 16' build

Testing

xcodebuild test -project SubFeed.xcodeproj -scheme SubFeedApp -destination 'platform=iOS Simulator,name=iPhone 16'

Tests cover: RSS parsing, Shorts detection, data retention, backup round-trip, credential migration, channel search, OPML import, and model validation.

Design Decisions

  • Standalone first: No server dependency. All data lives in on-device SwiftData.
  • Keychain for secrets: YouTube API keys stored in iOS Keychain, never in plaintext database fields.
  • API key via HTTP header: Uses X-Goog-Api-Key header rather than query string for YouTube API calls.
  • Conservative Shorts detection in RSS parser, aggressive in filter: The parser only marks clear Shorts. The filter heuristic is broader to catch edge cases. API verification provides the definitive answer.
  • 16:9 thumbnails only: The thumbnail fallback chain excludes 4:3 letterboxed variants (hqdefault.jpg, sddefault.jpg).
  • 20% auto-watch threshold: Inline playback marks a video as watched once 20% has been viewed.
  • Dedup from full database, not filtered view: To prevent silent video loss from unique constraint violations.

Security

  • API keys: iOS Keychain (Security framework), transmitted via X-Goog-Api-Key HTTP header
  • Backup exports: exclude sensitive fields (apiKey, serverToken)
  • No analytics, no tracking, no third-party SDKs
  • Zero network dependencies by default (optional YouTube API key)

License

Private. Not yet licensed for distribution.

About

iOS app for following YouTube subscriptions via RSS feeds — no Google account required

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages