Adds the new Rust-based UI (iced), backend service, shared Swift models, CI/CD workflows, build scripts, and project documentation.
8.0 KiB
Phase 5: Advanced Features Implementation Summary
Overview
Phase 5 implements advanced features for the MovieMapper iOS app, focusing on offline-first architecture and enhanced tagging capabilities.
1. Offline-First Architecture
LocalCache.swift
Location: Sources/Services/LocalCache.swift
Features:
- Caches show search results in UserDefaults with 7-day expiration
- Supports caching of individual shows and arrays of shows
- Automatic cache expiration handling
- Methods:
cacheShows(key:shows:)- Cache an array of showsgetCachedShows(key:)- Retrieve cached showscacheSearchResults(key:shows:)- Cache search resultsgetCachedSearchResults(key:)- Get cached search resultscacheShowDetails(key:show:)- Cache individual show detailsgetCachedShowDetails(key:)- Get cached show detailsclearCache()- Clear all cached dataclearCacheEntry(key:)- Clear specific cache entry
Integration:
- Used by
TVDBClientto cache search results and show details - Provides offline access to recently searched shows and show details
- Automatically expires old cache entries
OfflineManager.swift
Location: Sources/Services/OfflineManager.swift
Features:
- Monitors network connectivity using Combine
- Queues operations when offline for later execution
- Automatic retry mechanism (up to 3 attempts)
- Persistent operation queue using UserDefaults
- Methods:
queueOperation(description:operation:)- Add operation to queueprocessQueue()- Process queued operationsloadQueue()- Load queue from UserDefaults on app launchclearQueue()- Clear all queued operationsgetQueuedOperations()- Get current queue
Network Status:
isOnline: Bool- Current connectivity statusstatus: NetworkStatus-.onlineor.offline
Operation Structure:
- UUID-based operation tracking
- Retry count tracking
- Error logging for failed operations
2. Tagging System
TagManager.swift
Location: Sources/Services/TagManager.swift
Features:
- Add/remove tags on files
- Move tagged files to Jellyfin-compatible folders
- Automatic folder creation for target folders
- Audit logging for all tagging operations
Methods:
addTag(_tag:to:in:)- Add a tag to a fileremoveTag(_tag:from:in:)- Remove a tag from a filehasTag(_tag:in:)- Check if file has a taggetAllTags(for:)- Get all tags for a filemoveTaggedFiles(_files:to:in:)- Move tagged files to a foldermoveFilesWithTags(_files:in:)- Move files to appropriate folders based on their tagsgetTaggedFiles(in:)- Get all tagged files in a directory
Jellyfin Compatible Folders:
extra→extras/behindTheScenes→behind-the-scenes/delete→delete/
Result Structure:
public struct MoveTaggedFilesResult {
let success: Bool
let movedCount: Int
let failedCount: Int
let movedFiles: [MediaFile]
let failedFiles: [MoveFailure]
}
3. UI Integration
FileListView.swift Updates
New Features:
- Toggle tagging mode with floating action button
- Visual tag badges on files showing tag state
- Floating action button for moving all tagged files
- Individual file tag toggling when in tagging mode
Floating Action Button:
- Two buttons stacked vertically:
- "Tag Files" - Toggle tagging mode on/off
- "Move All Tagged" - Move all tagged files to appropriate folders
- Auto-hides when not needed
- Smooth animation for appearance/disappearance
Tag Badges:
- Shows tag name with first letter capitalized
- Color-coded based on tag type (purple for extra, orange for behind-the-scenes, red for delete)
- Tap to toggle tag when in tagging mode
- Visual feedback with border and shadow
4. TVDB Client Updates
TVDBClient.swift
Updates:
- Uses
LocalCachefor caching search results and show details - Removed manual UserDefaults caching
- Cleaner separation of concerns
- Offline-capable search and show details
Caching Behavior:
- Search results cached with key
search_{query} - Show details cached with key
show_{id} - Episodes cached with key
episodes_{showId}_{seasonNumber} - Cache expires after 7 days
5. Data Model Updates
SharedModels Files (all made public)
Updated to use public access control:
MediaFile.swift- File structure with tagsShow.swift- Show structure with caching supportSeason.swift- Season structureEpisode.swift- Episode structureTagType.swift- Tag type enum (extra, behindTheScenes, delete)TaggedFile.swift- Tagged file structure
6. Package Structure
Package.swift Updates
Structure:
- All source files in
Sources/directory - SharedModels included in Sources directory
- Proper module structure for Swift Package Manager
- Dependencies: FFmpegKitSwift, Alamofire, ReactiveSwift
Integration Summary
File Flow
-
Search:
- User searches for show → TVDBClient checks cache first
- If not in cache, fetch from network and cache result
- Offline: shows cached results
-
File Scanning:
- FileScanner scans directory (completely offline)
- Files loaded with metadata (duration, quality, FPS)
- Files can be tagged locally
-
Tagging:
- User toggles tagging mode
- Tags added/removed via TagManager
- Tags persisted to
.metadatafile - Audit log updated for each action
-
File Movement:
- User selects "Move All Tagged"
- TagManager moves files to appropriate folders
- Audit log entry created
- Files removed from UI
Offline Capabilities
- File scanning: 100% offline
- Tagging: 100% offline
- File movement: 100% offline
- TVDB search: Cached results available offline
- TVDB show details: Cached results available offline
- Episode data: Cached results available offline
Testing Recommendations
-
LocalCache:
- Cache write/read operations
- Cache expiration (7-day test)
- Clear cache functionality
-
OfflineManager:
- Queue operations while offline
- Automatic processing when online
- Retry mechanism (3 attempts)
- Persistence across app launches
-
TagManager:
- Add/remove tags
- Move files to correct folders
- Folder creation (extras, behind-the-scenes, delete)
- Audit logging
-
FileListView:
- Tagging mode toggle
- Tag badge display
- Floating action button visibility
- Move all tagged files
Known Limitations
-
FileScanner:
- Non-recursive scanning (current directory only)
- No parent directory navigation yet
- Tag state lost on directory change
-
LocalCache:
- UserDefaults based (not suitable for large datasets)
- 7-day expiration
- No manual cache management UI
-
OfflineManager:
- No UI feedback for queued operations
- No priority system for operations
- Limited retry options
Next Steps (Future Phases)
- Phase 6: Build & Distribution
- Phase 7: Advanced Features
- iCloud sync
- File preview
- Bulk operations
- Advanced filtering
Files Created/Modified
Created:
Sources/Services/LocalCache.swiftSources/Services/OfflineManager.swiftSources/Services/TagManager.swiftSources/SharedModels/(copied from parent directory)
Modified:
Sources/Services/TVDBClient.swift- Uses LocalCacheSources/UI/FileListView.swift- Enhanced tagging UISources/SharedModels/*.swift- Made publicPackage.swift- Updated targets
Summary
Phase 5 successfully implements:
- ✅ Local caching of show search results (7-day expiration)
- ✅ File scanning works completely offline
- ✅ TVDB features optional (internet required for fresh data)
- ✅ TagManager with addTag, removeTag, moveTaggedFiles methods
- ✅ Jellyfin compatible folders (extras/, behind-the-scenes/, delete/)
- ✅ Floating action button for moving all tagged files
- ✅ Tag state persistence
- ✅ Audit logging for tagging operations
The implementation follows the iOS app architecture and integrates seamlessly with existing services.