| fastlane | ||
| Flixarr | ||
| Flixarr.xcodeproj | ||
| FlixarrTests | ||
| FlixarrWidgets | ||
| NotificationServer | ||
| .gitignore | ||
| AccentColor.swift | ||
| add_diagnostics_view_to_xcode.rb | ||
| add_files_to_xcode.rb | ||
| add_model_files_to_xcode.rb | ||
| add_poster_cache_to_xcode.rb | ||
| add_service_files_to_xcode.rb | ||
| add_test_files_to_xcode.rb | ||
| APP_STORE_CHECKLIST.md | ||
| APP_STORE_METADATA.md | ||
| APP_STORE_METADATA.txt | ||
| APP_STORE_REVIEWER_CREDENTIALS.txt | ||
| APP_STORE_SUBMISSION_INFO.txt | ||
| APP_STORE_SUBMISSION_SAFE.txt | ||
| capture-screenshots.sh | ||
| CLAUDE.md | ||
| CONTINUATION_NOTES.md | ||
| CRITICAL_ACTIONS_BEFORE_SUBMIT.md | ||
| feral-setup-info.txt | ||
| FERAL_SETUP_COMPLETE.md | ||
| FERAL_SETUP_GUIDE.md | ||
| FILTER_IMPLEMENTATION_PLAN.md | ||
| fix_poster_cache_path.rb | ||
| FlixarrLogo.svg | ||
| Gemfile | ||
| Gemfile.lock | ||
| IMPLEMENTATION_PLAN.md | ||
| MULTI-PROFILE-PLAN.md | ||
| NETFLIX-GENRE.md | ||
| PHASE3_COMPLETE.md | ||
| PHASE4_COMPLETE.md | ||
| PHASE4_IMPLEMENTATION_DETAILS.md | ||
| PHASE7_COMPLETION.md | ||
| PHASE8_COMPLETION.md | ||
| PHASE9_COMPLETION.md | ||
| PHASE_3.1_INVESTIGATION.md | ||
| PHASES_7_8_SUMMARY.md | ||
| PLEX_CONNECTION_DESIGN.md | ||
| POSTER_CACHE_OPTIMIZATION.md | ||
| privacy.html | ||
| PRIVACY_HOSTING_GUIDE.md | ||
| PRIVACY_POLICY.md | ||
| PUSH_NOTIFICATIONS_PLAN.md | ||
| README.md | ||
| ROADMAP.md | ||
| SUBMISSION_CHECKLIST.md | ||
| USER_GUIDE_COMPOSITE_GENRES.md | ||
Flixarr
A native iOS app for managing your Sonarr (TV series) and Radarr (movies) instances with integrated Plex playback support.
Features
Home Dashboard
- At-a-Glance Overview: Comprehensive dashboard showing library statistics, system status, and quick actions
- Statistics Cards: Total series/movies, episodes, upcoming content, and Plex connection status
- Continue Watching: Resume your in-progress content with visual progress bars
- AI Recommendations: Personalized suggestions based on your viewing habits
- Composite Genres: Netflix-style intelligent genre categories combining language, country, and traditional genres
- Recently Added to Plex: View the 10 most recent items added to your Plex library with direct playback
- Upcoming Content: Horizontal scrolling cards showing next releases
- Quick Actions: Fast access to add content, view calendar, and check activity
- System Status: Real-time monitoring of Sonarr, Radarr, and Plex connection states
Core Management
- Dual Service Support: Manage both Sonarr (TV series) and Radarr (movies) from a single app
- Modern List Views: Card-based layouts with gradient icons, metadata pills, and status badges
- Browse Libraries: View all your series and movies with posters, metadata, and statistics
- Search & Add Content: Modern search cards with quality profile and root folder selection
- Delete Content: Remove series or movies from your library with optional file deletion
- Activity Queue: Monitor active downloads with gradient progress bars and status indicators
Plex Integration
- Recently Added Section: See what's new in Plex with direct playback from home screen
- Continue Watching: Resume playback from where you left off with progress tracking
- AI-Powered Recommendations: Personalized content suggestions based on watch history and preferences
- Multi-Server Support: Connect to multiple Plex servers with automatic discovery via Plex.tv
- Advanced Connection Management: Intelligent connection probing, caching, and automatic failover
- Connection Diagnostics: Built-in diagnostics view to troubleshoot connection issues
- Connection Types: Supports both Plex.Direct and custom domain connections
- Content Availability: Automatic detection of content availability in your Plex library
- Fullscreen Browser Playback: Stream content with fullscreen Plex web player and improved controls (default)
- Multiple Playback Options: Choose between browser, Plex app, or in-app AVPlayer
- Context Menus: Long-press for playback options on any Plex-available content
- Watch Progress: View watch progress indicators for tracked content
- Episode Navigation: Previous/next episode buttons in video player for binge-watching
- Profile Support: Maintains Plex profile authentication and PIN protection
- Enhanced Authentication: Seamless token-based authentication for web playback
- TMDB & TVDB Integration: Enhanced metadata fetching from TheMovieDB and TheTVDB
Multi-Profile Support
- Multiple Configurations: Create and manage multiple server profiles with isolated settings
- Profile Switching: Quick switching between different Sonarr/Radarr/Plex configurations
- Profile Editor: Dedicated editor for creating and managing profiles
- Profile Picker: Easy-to-use profile selection interface
- Isolated Settings: Each profile maintains its own API keys, URLs, and preferences
Composite Genres (Netflix-Style)
- Intelligent Categorization: Automatically generates genre combinations like "Korean Thriller", "Japanese Anime", "Chinese Romance Drama"
- Multi-Dimensional Matching: Combines language, country, and traditional genres for precise categorization
- Rule-Based + ML: Uses both rule-based logic and ML clustering for comprehensive genre generation
- Auto-Refresh: Configurable auto-refresh period (15 minutes to 1 day) with manual refresh option
- Interactive Cards: Tap movies to play directly, tap series to see Netflix-style episode selector
- Episode Selector: Season picker with episode thumbnails, summaries, and playback integration
- Genre Explanations: Long-press any item to see why it was included in that genre
- Accent Color Theming: Genre cards follow the app's accent color for consistent design
- Smart Filtering: Only shows genres with at least 3 matching items and high confidence scores
Video Player
- In-App Playback: Native AVPlayer-based video playback
- Episode Navigation: Previous/next episode buttons for seamless binge-watching
- Progress Tracking: Automatic position saving and resume support
- Subtitle Support: Change subtitles during playback (may require restart)
- Audio Session Management: Proper audio category handling for background playback
- Fullscreen Mode: Automatic orientation lock in landscape for immersive viewing
- Watch History: Automatic recording for AI recommendations
- Series Context: Understands series/season/episode context for navigation
Continue Watching
- Progress Tracking: Automatically tracks playback position for all content
- Resume Playback: Pick up exactly where you left off
- Visual Progress Bars: See progress at a glance on content cards
- Cross-Session Sync: Progress persists across app launches
- Series & Movies: Works for both TV episodes and movies
- In-App Tracking: Tracks playback from VideoPlayerView
AI-Powered Recommendations
- Personalized Suggestions: Content recommendations based on your watch history
- Genre-Based Matching: Suggests similar content from your library
- Watch History Analysis: Learns from your viewing patterns
- Confidence Scores: Shows how well each recommendation matches your preferences
- Real-Time Updates: Recommendations refresh as you watch more content
- Privacy-Focused: All processing happens locally on device
Manual Import
- Failed Download Recovery: Manually import files when automatic import fails
- File Selection: View and select files with quality, episode/movie info, and rejection reasons
- Smart Auto-Selection: Automatically selects files without rejections
- Retry Logic: Automatic retry with delays for directory scanning
- Status Indicators: Clear status display showing "Download completed" and "• Importing" states
Calendar & Navigation
- Unified Calendar: View upcoming episodes and movie releases in a monthly calendar
- Modern Calendar Design: Better day cell styling with gradient icons for events
- Tab Navigation: Tap calendar items to navigate to series/movies with automatic tab switching
- Date Selection: Filter calendar items by selected date
- Calendar Widget: iOS Home Screen widget showing upcoming releases
Queue Management
- Real-Time Status: View download progress with gradient progress bars
- Queue Actions: Remove items, blocklist releases, or trigger manual retry
- Import Status: Visual indicators for import failures with manual import button
- Multi-Source Display: Combined view of Sonarr and Radarr queue items sorted by date
- Modern Cards: Status badges, metadata pills, and gradient progress visualization
- File Renaming: Preview and rename files before import with RenamePreviewSheet
Storage Management
- Directory Browser: Modern card-based directory picker with visual hierarchy
- Path Display: View current storage path for each series/movie
- Root Folder Selection: Choose storage location when adding new content
- Breadcrumb Navigation: Clear parent directory navigation
Modern Design System
- Gradient Icons: Color-coded icons for TV (cyan/blue) and Movies (indigo/purple)
- Status Badges: Capsule-shaped indicators for monitoring, download, and connection states
- Metadata Pills: Small pills displaying year, network, quality, and other metadata
- Progress Bars: Custom gradient-filled progress indicators
- Card Layouts: Consistent card-based design with shadows and rounded corners
- Loading States: Modern loading indicators with descriptive messages
- Empty States: Friendly empty state views with gradient icons
- Animations: Smooth transitions respecting accessibility preferences
Accessibility & Polish
- VoiceOver Support: Comprehensive accessibility labels and hints
- Dynamic Type: Scalable fonts supporting user preferences
- Reduced Motion: All animations respect accessibility settings
- High Contrast: Color-coded elements with sufficient contrast
- Touch Targets: Appropriately sized interactive elements
iOS Integration
- Siri Shortcuts: Add series/movies, check queue, and search via Siri
- Spotlight Search: Search your library directly from iOS Spotlight
- Home Screen Widget: Upcoming releases widget for quick access
- Accent Colors: Customize app appearance with 9 color options
- Dark Mode: Full support for light, dark, and automatic appearance modes
User Interface
- Native SwiftUI: Modern, native iOS interface built with SwiftUI
- Responsive Layout: Optimized for all iPhone screen sizes
- Pull to Refresh: Refresh content with simple pull-down gesture
- Quick Search: Fast search within series and movie lists
- Tab Navigation: Organized into Home, Series, Movies, Calendar, Activity, Status, Settings, and Support tabs
Requirements
- iOS 17.0 or later
- Xcode 15.0 or later (for building from source)
- Sonarr v3 API or Radarr v3 API
- (Optional) Plex Media Server for playback integration
Getting Started
Installation
- Clone or download this repository
- Open
Flixarr.xcodeprojin Xcode - Select your target device or simulator
- Build and run the project (⌘R)
Configuration
Sonarr Setup
- Open the app and go to the Settings tab
- Scroll to the Sonarr section
- Enter your Sonarr server URL (e.g.,
http://192.168.1.100:8989) - Enter your API key (found in Sonarr: Settings → General → Security → API Key)
- Tap Test Connection to verify the settings
Radarr Setup
- In the Settings tab, scroll to the Radarr section
- Enter your Radarr server URL (e.g.,
http://192.168.1.100:7878) - Enter your API key (found in Radarr: Settings → General → Security → API Key)
- Tap Test Connection to verify the settings
Plex Setup (Optional)
- In the Settings tab, scroll to the Plex section
- Tap Sign in with Plex
- Complete the OAuth authentication flow in Safari
- Select your Plex server from the available servers list (Plex.Direct connections recommended)
- The app will automatically check content availability
- (Optional) Configure playback preference: Browser (default), Plex App, In-App Player, or Auto
Project Structure
Flixarr/
├── FlixarrApp.swift # App entry point with service initialization
├── ContentView.swift # Main tab view with navigation coordination
├── Models/
│ ├── Series.swift # Series data model (Sonarr)
│ ├── Episode.swift # Episode data model (Sonarr)
│ ├── Movie.swift # Movie data model (Radarr)
│ ├── CalendarItem.swift # Unified calendar item model
│ ├── MediaItem.swift # Unified Plex media snapshot
│ ├── MediaFeatures.swift # Feature vectors for ML processing
│ ├── CompositeGenre.swift # Composite genre definition
│ ├── CompositeGenreMembership.swift # Item-genre relationship tracking
│ ├── Profile.swift # Multi-profile configuration model
│ ├── Recommendation.swift # AI recommendation model
│ ├── RecentlyWatched.swift # Watch history tracking model
│ ├── PlexConnection.swift # Plex connection configuration
│ ├── CachedConnection.swift # Cached connection data
│ ├── ConnectionScore.swift # Connection quality scoring
│ ├── NetworkIdentifier.swift # Network identification model
│ ├── TMDBMedia.swift # TheMovieDB metadata model
│ ├── TVDBMedia.swift # TheTVDB metadata model
│ ├── AccentColor.swift # Accent color preferences
│ └── AppearanceMode.swift # Theme preferences
├── Services/
│ ├── SonarrService.swift # Sonarr API client with queue & manual import
│ ├── RadarrService.swift # Radarr API client with queue & manual import
│ ├── PlexService.swift # Plex API client with OAuth
│ ├── PlexNotificationService.swift # Recently added to Plex matching
│ ├── PlexMediaItemFetcher.swift # Plex library metadata fetcher
│ ├── PlexWebView.swift # Plex OAuth & web playback views
│ ├── PlexConnectionManager.swift # Plex connection orchestration
│ ├── PlexConnectionProber.swift # Connection health checking
│ ├── PlexConnectionSelector.swift # Intelligent connection selection
│ ├── PlexConnectionCache.swift # Connection caching service
│ ├── CompositeGenreService.swift # Composite genre orchestration
│ ├── GenreRuleEngine.swift # Rule-based genre generation
│ ├── MLProcessor.swift # ML clustering for genre suggestions
│ ├── CacheService.swift # Local caching with TTL
│ ├── CalendarCacheService.swift # Dedicated calendar caching
│ ├── PosterCacheService.swift # Poster image caching
│ ├── ExternalMediaCacheService.swift # External media caching
│ ├── PlaybackCoordinator.swift # Playback routing logic
│ ├── ContinueWatchingService.swift # Watch progress tracking
│ ├── RecommendationService.swift # AI-powered recommendations
│ ├── SeriesWatchStateService.swift # Series watch state tracking
│ ├── ProfileManager.swift # Multi-profile management
│ ├── MediaItemResolver.swift # Media item resolution logic
│ ├── TMDBService.swift # TheMovieDB API client
│ ├── TVDBService.swift # TheTVDB API client
│ ├── EncryptionService.swift # Settings encryption for sync
│ ├── SharedDataManager.swift # App group data sharing
│ └── SpotlightService.swift # Spotlight search indexing
├── Intents/
│ ├── AppShortcuts.swift # Siri Shortcuts definitions
│ ├── AddSeriesIntent.swift # Add series via Siri
│ ├── AddMovieIntent.swift # Add movie via Siri
│ ├── CheckQueueIntent.swift # Check queue via Siri
│ ├── SearchMediaIntent.swift # Search content via Siri
│ └── IntentModels.swift # Intent data models
├── Views/
│ ├── HomeView.swift # Dashboard with stats, genres, recently added
│ ├── GenreMediaCard.swift # Composite genre media cards
│ ├── GenreExplanationSheet.swift # Genre membership explanation
│ ├── PlexSeriesEpisodeSheet.swift # Netflix-style episode selector
│ ├── ContinueWatchingCard.swift # Continue watching media cards
│ ├── RecommendationCard.swift # AI recommendation cards
│ ├── RecommendationSection.swift # Recommendation section layout
│ ├── PlexRecentlyAddedCard.swift # Recently added Plex content cards
│ ├── ProfileEditorView.swift # Multi-profile editor
│ ├── ProfilePickerSheet.swift # Profile selection sheet
│ ├── SeriesListView.swift # Modern series list with cards
│ ├── SeriesDetailView.swift # Series details with modern UI
│ ├── SeriesAddConfigView.swift # Series configuration with modern UI
│ ├── MovieListView.swift # Modern movie list with cards
│ ├── MovieDetailView.swift # Movie details with modern UI
│ ├── MovieAddConfigView.swift # Movie configuration with modern UI
│ ├── AddSeriesView.swift # Modern search and add series
│ ├── AddMovieView.swift # Modern search and add movies
│ ├── CalendarView.swift # Modern monthly calendar view
│ ├── ManualImportView.swift # Manual import file selection
│ ├── RenamePreviewSheet.swift # File rename preview interface
│ ├── PlexConnectionDiagnosticsView.swift # Plex connection troubleshooting
│ ├── SettingsView.swift # Modern settings with gradient icons
│ ├── ShortcutsSettingsView.swift # Siri Shortcuts configuration
│ ├── ServerStatusView.swift # Server status with modern cards
│ ├── DirectoryBrowserView.swift # Modern directory picker
│ ├── VideoPlayerView.swift # In-app video playback with episode navigation
│ └── SupportView.swift # Support/donation information
├── Styles/
│ ├── ModernComponents.swift # Modern UI components (badges, pills, icons)
│ ├── DesignSystem.swift # Design constants (spacing, colors, gradients)
│ ├── ButtonStyles.swift # Standardized button styles
│ ├── ContainerStyles.swift # Card and container styles
│ ├── AnimationStyles.swift # Animation modifiers
│ ├── FeedbackStyles.swift # Error and success feedback
│ └── ProgressViewStyles.swift # Progress view configurations
├── Widgets/
│ └── CalendarWidget.swift # Home Screen widget for upcoming content
└── Assets.xcassets/ # App assets and icons
API Integration
Sonarr v3 API
GET /api/v3/series- Fetch all seriesGET /api/v3/series/{id}- Fetch series detailsPOST /api/v3/series- Add new seriesDELETE /api/v3/series/{id}- Remove seriesGET /api/v3/episode- Fetch episodes for a seriesGET /api/v3/calendar- Fetch upcoming episodesGET /api/v3/queue- Fetch download queueDELETE /api/v3/queue/{id}- Remove from queuePOST /api/v3/queue/grab/{id}- Retry downloadGET /api/v3/manualimport- Fetch files for manual importPOST /api/v3/command- Execute commands (manual import, rescan, etc.)GET /api/v3/rootfolder- Fetch available root foldersGET /api/v3/qualityprofile- Fetch quality profilesGET /api/v3/series/lookup- Search for seriesGET /api/v3/filesystem- Browse directory structure
Radarr v3 API
GET /api/v3/movie- Fetch all moviesPOST /api/v3/movie- Add new movieDELETE /api/v3/movie/{id}- Remove movieGET /api/v3/calendar- Fetch upcoming movie releasesGET /api/v3/queue- Fetch download queueDELETE /api/v3/queue/{id}- Remove from queuePOST /api/v3/queue/grab/{id}- Retry downloadGET /api/v3/manualimport- Fetch files for manual importPOST /api/v3/command- Execute manual import commandGET /api/v3/rootfolder- Fetch available root foldersGET /api/v3/qualityprofile- Fetch quality profilesGET /api/v3/movie/lookup- Search for moviesGET /api/v3/filesystem- Browse directory structure
Plex API
POST /pins- Initiate OAuth PIN authenticationGET /pins/{id}- Poll for authentication completionGET /pms/resources- Discover available Plex serversGET /library/sections- Fetch library sectionsGET /library/sections/{id}/all- Fetch all library content with metadataGET /library/metadata/{ratingKey}- Fetch show/season metadataGET /library/metadata/{ratingKey}/children- Fetch episodes for a seasonGET /video/:/transcode/universal/start.m3u8- Get HLS stream URL
TMDB API (TheMovieDB)
- Enhanced metadata fetching for movies and TV shows
- Poster and backdrop image retrieval
- Cast and crew information
- External ID mapping (IMDB, TVDB)
TVDB API (TheTVDB)
- TV series metadata enrichment
- Episode information and air dates
- Series artwork and banners
- External ID cross-referencing
Data Storage
UserDefaults Keys
- Sonarr:
sonarr_url,sonarr_api_key - Radarr:
radarr_url,radarr_api_key - Plex:
plex_token,plex_username,plex_client_id,plex_selected_server,plex_server_url - Composite Genres:
composite_genres_enabled,composite_genre_refresh_hours,composite_genre_last_generation - Profiles:
active_profile_id,profiles_list - Recommendations:
recommendation_enabled,recommendation_refresh_interval - Continue Watching:
continue_watching_enabled - External Services:
tmdb_api_key,tvdb_api_key - Theme:
appearance_mode(system/light/dark),accent_color
Local Cache
- Series/Movies: 5-minute TTL
- Episodes: 10-minute TTL
- Queue: 30-second TTL
- Calendar: 5-minute TTL (CalendarCacheService)
- Composite Genres: 24-hour TTL
- Media Items/Features: 24-hour TTL
- Posters/Images: Permanent cache with LRU eviction (PosterCacheService)
- Plex Connections: Smart caching with probing (PlexConnectionCache)
- Continue Watching: Session-based cache
- Recommendations: 6-hour TTL
- External Media: 24-hour TTL (ExternalMediaCacheService)
- Files stored in
Documents/Cache/directory
Architecture
State Management
- @StateObject + @EnvironmentObject Pattern: Services are created as
@StateObjectinFlixarrAppand injected via@EnvironmentObject - ObservableObject Services: Core services include:
- Media Management:
SonarrService,RadarrService - Plex Integration:
PlexService,PlexNotificationService,PlexConnectionManager - Recommendations:
RecommendationService,ContinueWatchingService - Genres:
CompositeGenreService - Profiles:
ProfileManager - External APIs:
TMDBService,TVDBService
- Media Management:
- async/await: All network operations use Swift's modern concurrency
- MainActor: UI updates properly dispatched to main thread
Service Layer
Each service is an ObservableObject that:
- Manages authentication state (API keys/tokens in UserDefaults)
- Publishes data arrays (
@Published var series,@Published var movies) - Publishes loading state (
@Published var isLoading) - Publishes error messages (
@Published var errorMessage) - Uses custom URLSession with appropriate timeouts
- Updates UI state safely via
await MainActor.run { } - Implements caching with TTL for performance
Design System
- ModernComponents: Reusable UI components (GradientIcon, StatusBadge, MetadataPill, etc.)
- Consistent Spacing: Standardized spacing scale (xs, sm, md, lg, xl, xxl, xxxl)
- Color Palette: Brand colors for TV (cyan/blue) and Movies (indigo/purple)
- Gradients: Custom gradient definitions for visual polish
- Animations: Smooth transitions respecting accessibility preferences
Navigation
- NavigationCoordinator: Coordinates tab switching and deep linking
- Tab-Based Navigation: Main content organized in 8 tabs (Home, Series, Movies, Calendar, Activity, Status, Settings, Support)
- Deep Linking: Calendar items can navigate to series/movies with automatic tab switching
- Spotlight Integration: Content searchable from iOS Spotlight
- Siri Shortcuts: Voice-activated actions for common tasks
Manual Import Feature
How It Works
- Queue item shows import failure with manual import button (green import icon)
- Tap button to open ManualImportView
- App fetches available files with metadata (quality, episodes/movie, rejections)
- Files without rejections are auto-selected
- Review and modify selection as needed
- Tap "Import" to queue the manual import command
- Queue refreshes automatically after import
API Flow
1. GET /api/v3/manualimport?downloadId=X&folder=Y&filterExistingFiles=false
→ Returns list of files with metadata
2. POST /api/v3/command
Body: {
"name": "ManualImport",
"files": [
{
"path": "/path/to/file.mkv",
"seriesId": 152, // or movieId for Radarr
"episodeIds": [15780],
"quality": { ... },
"languages": [ ... ],
"releaseGroup": "...",
"downloadId": "..."
}
],
"importMode": "auto"
}
→ Queues import command, returns 201 Created
State Management
- Uses
ManualImportInfostruct with.sheet(item:)to ensure proper state capture - Avoids SwiftUI timing issues with reliable data passing
- Implements retry logic for directory scanning delays
Composite Genres Feature
How It Works
- Fetches all media items from Plex with comprehensive metadata (language, country, genres, studios)
- Generates feature vectors from each item for ML processing
- Uses dual-method genre generation:
- Rule-Based Engine: Deterministic combinations (e.g., "Korean" + "Drama" → "Korean Drama")
- ML Clustering: K-means clustering on feature vectors for pattern discovery
- Merges and filters genres (minimum 3 items, confidence thresholds)
- Creates memberships linking items to genres with explanations
- Caches results with 24-hour TTL for performance
Genre Components
Each composite genre combines:
- Language: Chinese, Korean, Japanese, English, Spanish, French
- Country: China, South Korea, Japan, US, UK, France
- Primary Genre: Action, Drama, Comedy, Horror, Thriller, Romance, Sci-Fi, Animation
- Secondary Genres: Additional genre modifiers for precision
User Controls
- Enable/Disable: Toggle in Settings → Composite Genres
- Auto-Refresh: Configurable period (15 minutes to 1 day)
- Manual Refresh: Force immediate regeneration
- Server Change: Automatically refreshes when Plex server changes
API Flow
1. GET /library/sections → Fetch all Plex library sections
2. GET /library/sections/{id}/all → Fetch all items with metadata
3. Generate MediaItems → Convert Plex data to unified format
4. Generate Features → Extract multi-dimensional features
5. GenreRuleEngine → Rule-based genre generation
6. MLProcessor → ML-assisted clustering
7. Merge & Filter → Combine and quality check
8. Create Memberships → Link items to genres with explanations
Advanced Plex Connection Management
PlexConnectionManager
Flixarr uses an intelligent connection management system for reliable Plex server access:
Features:
- Connection Probing: Actively tests all available connection methods (direct, relay, local)
- Quality Scoring: Ranks connections based on latency, bandwidth, and reliability
- Automatic Failover: Seamlessly switches to backup connections if primary fails
- Smart Caching: Remembers successful connections for faster future access
- Network Awareness: Adapts to network changes (WiFi, cellular, VPN)
- Connection Diagnostics: Built-in troubleshooting view for connection issues
Components:
PlexConnectionManager: Orchestrates connection lifecycle and selectionPlexConnectionProber: Tests connection health and measures performancePlexConnectionSelector: Chooses optimal connection based on scoring algorithmPlexConnectionCache: Caches successful connections with TTL
Connection Priority:
- Local network (direct IP)
- Plex.Direct (secure relay)
- Custom domains
- Plex relay (fallback)
Diagnostics View: Access via Settings → Plex → Connection Diagnostics to:
- View all available connections
- See real-time connection scores
- Test individual connections
- View detailed error messages
- Force connection refresh
Security
- API keys stored in UserDefaults (consider iOS Keychain for production)
- Plex OAuth tokens stored securely in UserDefaults
- HTTPS enforced by default (NSAppTransportSecurity allows local HTTP exceptions)
- No credentials transmitted; uses Plex OAuth PIN flow
- Encryption key for settings sync stored in iOS Keychain (never syncs to iCloud)
Building & Testing
Build Commands
# Build for simulator
xcodebuild -project Flixarr.xcodeproj -scheme Flixarr -sdk iphonesimulator build
# Build for specific device
xcodebuild -project Flixarr.xcodeproj -scheme Flixarr -configuration Debug \
-destination 'platform=iOS Simulator,name=iPhone 15' build
# Clean build
xcodebuild -project Flixarr.xcodeproj -scheme Flixarr clean
Testing
# List available simulators
xcrun simctl list devices available
# Install and launch
xcrun simctl install booted path/to/Flixarr.app
xcrun simctl launch booted com.sangarr.app
# Monitor logs
log stream --predicate 'processImagePath contains "Flixarr"' --level debug
iOS Integration Features
Siri Shortcuts
Flixarr supports the following Siri Shortcuts:
- Add Movie: Voice-activated movie search and addition
- Add Series: Voice-activated series search and addition
- Check Queue: Quick queue status check
- Search for Movie/Series: Voice search functionality
Spotlight Search
- All series and movies in your library are indexed in iOS Spotlight
- Search directly from home screen to quickly access content
- Tapping search results opens the app to the specific item
Home Screen Widget
- Calendar Widget: Shows upcoming releases on your home screen
- Updates automatically to keep you informed of new content
- Available in multiple widget sizes
Customization
- 9 Accent Colors: Personalize the app with your preferred color scheme
- Appearance Modes: Light, Dark, or System automatic
- Playback Preferences: Configure default playback method (Browser, Plex App, In-App)
Known Limitations
- Manual import requires both
downloadIdandfolderpath from queue item - First manual import load may require 10+ seconds for server directory scanning
- Recently Added to Plex requires at least one service (Sonarr or Radarr) to be configured
- Composite Genres require Plex to be configured and at least 3 items per genre
- Cache invalidation is time-based (TTL), not event-based
- Genre generation accuracy depends on Plex metadata quality (language, country, genres)
- AI Recommendations require sufficient watch history (minimum 5 watched items)
- Continue Watching only tracks playback within the app (not external Plex clients)
- Profile switching requires app restart to fully apply all settings
- TMDB/TVDB integration requires valid API keys (optional feature)
Plex Playback
Browser is Default: The app uses in-app browser playback by default instead of the native Plex app due to known issues with Plex's iOS app deep linking.
Plex App Deep Linking Issues (as of v2025.31.1):
- Navigation Failure: The
plex://URL scheme opens the Plex app but navigates to the home screen instead of the specific content - Managed Profiles with PINs: When Plex profiles have PIN protection enabled, deep links cause an infinite PIN loop:
- App accepts the PIN
- Attempts to play content
- Loses profile context
- Requests PIN again → repeat
- No Profile Context: The deep link URL scheme doesn't support passing profile authentication or user context
Recommended Solution:
- Keep default playback set to "Browser" in Settings → Playback Preference
- The in-app browser provides:
- ✅ Reliable playback every time
- ✅ Full Plex web interface with all features
- ✅ Proper authentication with profile context
- ✅ No PIN issues
- ✅ True fullscreen with tap-to-show overlay controls
Plex App Option:
- You can still try using the Plex app by changing Settings → Playback Preference to "Always Plex App"
- Or use the context menu (long-press Play button) → "Open in Plex App"
- Note: This may not work reliably due to the issues above
Future Enhancements
See IMPLEMENTATION_PLAN.md for detailed roadmap. Planned features include:
- Push Notifications: Real-time notifications for downloads and Plex availability (Phase 3.2)
- Additional Widgets: Continue watching and recommendations widgets (Phase 3.3)
- Enhanced Plex Integration: Watch history sync with external Plex clients, auto-play when ready (Phase 3.4)
- Dynamic Type Support: Full support for iOS Dynamic Type accessibility
- Series/Movie Rescan: Manual rescan functionality for library updates
- Advanced Recommendation Tuning: User-adjustable recommendation preferences and filters
Contributing
This is a personal project for managing media servers. Feel free to fork and customize for your own use.
License
This project is provided as-is for personal use.