The DBMultiverse target serves as the core of the application, integrating functionality from the other modules (DBMultiverseComicKit, DBMultiverseParseKit, and DBMultiverseWidgets) to deliver the primary user experience. This target defines the main app logic, user interface, and navigation.
- Purpose: Entry point for the app.
- Features:
- Displays the
WelcomeViewfor first-time users. - Transitions to
MainFeaturesViewafter the initial setup.
- Displays the
- Dependencies:
ComicLanguagefor language preferences.ChapterLoaderAdapterfor chapter loading.
- Purpose: Guides new users through initial setup.
- Features:
- Language selection.
- Disclaimer and introduction text.
- Smooth animations for transitioning between states.
- Dependencies:
LanguagePickerfor language selection.DisclaimerViewfor displaying terms.
- Purpose: Provides navigation for the settings feature.
- Features:
- Dynamically loads cached chapters.
- Allows clearing cache and updating language preferences.
- Links to external resources (e.g., Authors, Help pages).
- Dependencies:
SettingsViewModelfor business logic.SettingsFormView,LanguageSelectionView, andCacheChapterListViewfor specific settings UI.
- Purpose: Core view that displays chapters and comics.
- Features:
- Navigation between comic pages and settings.
- Synchronizes data with SwiftData.
- Handles deep linking.
- Dependencies:
SwiftDataChapterListfor chapter storage.ChapterLoaderAdapterfor loading chapters.
- Purpose: Provide navigation stacks for different devices.
- Features:
- Tab-based navigation on iPhone.
- Navigation stack with settings integration on iPad.
- Dependencies:
ComicNavStackfor managing comic navigation.
- Purpose: Displays individual comic pages.
- Features:
- Handles navigation between pages.
- Fetches and caches comic page images.
- Updates reading progress.
- Dependencies:
ComicPageViewModelfor handling page data.ComicPageManagerfor business logic.
- Purpose: Central ViewModel managing chapters and user progress.
- Key Functions:
loadData(language:): Fetches chapter data for the specified language.updateCurrentPageNumber(_:comicType:): Updates the user's current page.startNextChapter(_:): Prepares the next chapter for reading.
- Dependencies:
ChapterLoaderfor fetching chapter data.UserDefaultsfor storing progress viaAppStorage.
- Purpose: Manages fetching, caching, and displaying comic pages.
- Key Functions:
loadPages(_:): Fetches comic pages from cache or network.updateCurrentPageNumber(_:): Updates reading progress.saveChapterCoverPage(_:): Saves cover image metadata.
- Dependencies:
ComicImageCachefor caching.ComicPageNetworkServicefor fetching images.ChapterProgressHandlerfor tracking progress.
- Purpose: Manages smart widget timeline reloading with debouncing and optimization.
- Location:
DBMultiverse/Sources/Widgets/WidgetTimelineManager.swift - Architecture:
@MainActor final classconforming toWidgetTimelineReloaderprotocol - Key Features:
- Smart Debouncing: 2-second delay on progress changes to prevent excessive widget updates
- Minimum Delta Threshold: Only reloads widgets when progress changes by at least 5%
- State Caching: Maintains cached
WidgetSyncStateto avoid redundant reloads - Force Reload: Chapter changes trigger immediate widget updates
- Automatic Completion Detection: Progress of 100% always triggers widget reload
- Key Methods:
notifyChapterChange(chapter:progress:): Forces immediate widget timeline reload when chapter changesnotifyProgressChange(progress:): Debounced progress update that respects minimum delta threshold
- Dependencies:
CoverImageManagerfor widget synchronization state persistenceWidgetCenterfor iOS widget timeline management
- Implementation Details:
- Uses
Taskfor async debouncing with cancellation support - Coordinates with
CoverImageManagerto persist widget sync state - Reloads timeline for widget kind defined by
WIDGET_KINDconstant
- Uses
- Purpose: Manages page-level comic image caching with metadata tracking and widget synchronization.
- Location:
DBMultiverse/Sources/Features/Comic/ComicImageCacheManager.swift - Architecture:
@MainActor structconforming toComicImageCacheprotocol - Cache Structure:
- Directory:
Caches/Chapters/Chapter_X/Page_Y.jpg - Metadata file:
Caches/Chapters/Chapter_X/metadata.json - Supports both single-page and double-page spread images
- Directory:
- Key Features:
- Double-Page Spread Support: Special handling for pages 8/9 and 20/21
- Metadata Tracking: JSON metadata for multi-page entries with
secondPageNumber - Widget Integration: Notifies
WidgetTimelineReloaderon cache changes - Cover Image Persistence: Delegates cover image saving to
CoverImageDelegate - Progress Tracking: Coordinates page updates with
ComicPageStore
- Key Methods:
updateCurrentPageNumber(_:readProgress:): Updates progress and notifies widget timelinesaveChapterCoverImage(imageData:metadata:): Saves cover with metadata and triggers chapter change notificationloadCachedImage(chapter:page:): Loads cached image, checking both single-page and metadata.json for multi-page spreadssavePageImage(pageInfo:): Saves page image and updates metadata.json for double-page spreads
- Dependencies:
ComicPageStore: Persists current page number to storageCoverImageDelegate: Manages cover image data and progressWidgetTimelineReloader: Notifies widget of cache changesComicImageCacheDelegate: Abstracts file system operations
- Metadata Format (for double-page spreads):
{ "pages": [ { "pageNumber": 8, "secondPageNumber": 9, "fileName": "Page_8-9.jpg" } ] }
- Purpose: Enables navigation via deep links using the
dbmultiverse://URL scheme. - Location:
DBMultiverse/Sources/Features/Main/DeepLinkNavigationViewModifier.swift - Architecture:
structconforming toViewModifier - Features:
- Parses incoming URLs to extract chapter numbers from the last path component
- Navigates directly to specific chapters using
NavigationPath - Distinguishes between story and specials using
ComicTypebased on chapter's universe property - Creates
ChapterRoutefor navigation stack management
- URL Format:
dbmultiverse://[path]/[chapterNumber] - Usage:
view.withDeepLinkNavigation(path: $navigationPath, chapters: chapterList)
- Implementation:
- Uses
.onOpenURLmodifier to intercept deep link URLs - Matches chapter number against available chapters array
- Determines comic type:
.storyif universe is nil,.specialsotherwise - Appends
ChapterRouteto navigation path for navigation
- Uses
- Purpose: Synchronizes
Chapterobjects with SwiftData storage. - Features:
- Automatically updates chapters in the database when new data is available.
The DBMultiverse app uses the Adapter pattern to bridge between modules and abstract external dependencies. Adapters implement protocols defined in DBMultiverseComicKit while coordinating with other modules.
- Purpose: Converts parsed chapter data from
DBMultiverseParseKittoChaptermodels used byDBMultiverseComicKit. - Location:
DBMultiverse/Sources/Features/Adapters/ChapterLoaderAdapter.swift - Protocol: Implements
ChapterLoaderfromDBMultiverseComicKit - Dependencies:
SharedComicNetworkingManager: Fetches HTML dataComicHTMLParser: Parses chapter list from HTML
- Implementation:
- Fetches data from provided URL
- Parses HTML using
ComicHTMLParser.parseChapterList(data:) - Maps
ParsedChapterobjects toChapterobjects via.toChapter()extension
- Purpose: Implements network fetching for comic page images.
- Location:
DBMultiverse/Sources/Features/Adapters/ComicPageNetworkServiceAdapter.swift - Protocol: Implements
ComicPageNetworkServicefromDBMultiverseComicKit - Dependencies:
SharedComicNetworkingManager: Network request managerComicHTMLParser: Extracts image source from page HTML
- Implementation:
- Fetches HTML page data from chapter URL
- Parses HTML to extract image source using
ComicHTMLParser.parseComicPageImageSource(data:) - Constructs full image URL using
.makeFullURLString(suffix:) - Fetches and returns the actual image data
- Purpose: Bridges the
CoverImageDelegateprotocol withCoverImageManagerimplementation. - Location:
DBMultiverse/Sources/Features/Adapters/CoverImageDelegateAdapter.swift - Protocol: Implements
CoverImageDelegate(defined inComicImageCacheManager.swift) - Dependencies:
CoverImageManagerfromDBMultiverseComicKit
- Implementation:
- Wraps
CoverImageManagerinstance - Delegates
saveCurrentChapterData(imageData:metadata:)to manager - Delegates
updateProgress(to:)to manager
- Wraps
- Usage: Used by
ComicImageCacheManagerto persist cover images and widget sync state
- Purpose: Abstracts file system operations for cache management.
- Location:
DBMultiverse/Sources/Features/Adapters/FileSystemOperationsAdapter.swift - Protocol: Implements
ComicImageCacheDelegate(defined inComicImageCacheManager.swift) - Dependencies:
FileManagerfor file operationsCacheDelegateAdapterfor cache directory URL resolution
- Implementation:
contents(atPath:): Reads file data usingFileManagercreateDirectory(at:withIntermediateDirectories:): Creates directory structurewrite(data:to:): Writes data to file URLgetCacheDirectoryURL(): Delegates toCacheDelegateAdapter
- Module Separation: Keeps
DBMultiverseComicKitindependent of parsing and networking details - Testability: Protocols allow easy mocking in tests
- Flexibility: Implementation details can change without affecting ComicKit consumers
- Dependency Inversion: High-level modules depend on abstractions, not concrete implementations
- Purpose: Defines supported comic languages with localized display names.
- Location:
DBMultiverse/Sources/Features/Shared/Language/ComicLanguage.swift - Type:
enumwithStringraw values, conforming toCaseIterable - Total Languages: 36 supported languages
- Key Languages:
- Western European: English, French, Spanish, German, Italian, Portuguese, Catalan, Dutch
- Eastern European: Polish, Russian, Croatian, Romanian, Bulgarian, Lithuanian, Hungarian
- Nordic: Swedish, Norwegian, Danish, Finnish
- Asian: Japanese, Chinese, Korean, Filipino
- Middle Eastern: Arabic, Hebrew, Turkish
- Regional Variants: Brazilian Portuguese, Latin Spanish, various French dialects
- Special: Parodie Salagir (parody version)
- Raw Value Format: Language codes matching DB Multiverse website URL structure
- Simple codes:
"en","fr","es" - Regional codes:
"pt_BR","es_CO","hu_HU"
- Simple codes:
- Display Names: Native language names (e.g., "Français" for French, "日本語" for Japanese)
- Integration:
- Used by
URLFactoryto generate language-specific URLs - Persisted in
UserDefaultsvia@AppStorageinWelcomeViewandSettingsView - Affects chapter list fetching and page image URLs
- Used by
- Location:
DBMultiverse/Sources/Features/Comic/ComicImageCacheManager.swift - Conformance:
WidgetTimelineManager - Actor Isolation:
@MainActor - Purpose: Defines interface for notifying widget timeline updates
- Methods:
notifyChapterChange(chapter:progress:): Notify when chapter changesnotifyProgressChange(progress:): Notify when reading progress changes
- Location:
DBMultiverse/Sources/Features/Comic/ComicImageCacheManager.swift - Actor Isolation:
@MainActor - Purpose: Abstracts persistence of current page number
- Methods:
updateCurrentPageNumber(_:comicType:): Update and persist current page
- Location:
DBMultiverse/Sources/Features/Comic/ComicImageCacheManager.swift - Conformance:
CoverImageDelegateAdapter - Actor Isolation:
@MainActor - Purpose: Manages cover image persistence and progress tracking
- Methods:
updateProgress(to:): Update reading progresssaveCurrentChapterData(imageData:metadata:): Save cover image with chapter metadata
- Location:
DBMultiverse/Sources/Features/Comic/ComicImageCacheManager.swift - Conformance:
FileSystemOperationsAdapter - Sendable: Yes
- Purpose: Abstracts file system operations for cache management
- Methods:
getCacheDirectoryURL(): Returns cache directory URLwrite(data:to:): Write data to file URLcontents(atPath:): Read file contents at pathcreateDirectory(at:withIntermediateDirectories:): Create directory structure
- Purpose: Navigation routing model for comic chapters
- Properties:
chapter: TheChapterobject to navigate tocomicType:ComicTypeenum (.storyor.specials)
- Usage: Used by
DeepLinkNavigationViewModifierand navigation system
- Purpose: Tracks chapter and progress state for widget synchronization
- Properties:
chapter: Current chapter numberprogress: Reading progress percentage (0-100)
- Usage: Persisted by
CoverImageManager, cached byWidgetTimelineManager
- Type:
enum - Cases:
.story: Main story chapters.specials: Special/universe chapters
- Purpose: Distinguishes between different comic content types for navigation and storage
- Purpose: Constructs URLs for fetching data using the base url for the website and the selected language.
- The app uses
SwiftDataChapteras the primary model for storing chapter data. - Data is synchronized automatically via view modifiers.