Proposal: Cross-platform EPUBView (iOS + macOS) #817
grighakobian
started this conversation in
Ideas
Replies: 1 comment
|
Hi Grigor, thanks for the proposal. macOS support and a native SwiftUI navigator are definitely part of our long-term vision, so the intent is very much aligned. That said, a few concerns before we go further. On macOS support: This is a worthy goal, but the navigator is the last piece. All other modules need to be made macOS-compatible first. And it's something we'd only take on after shipping v4 with Swift 6 support. So a revised navigator proposal would be premature at this stage. On design direction: Keeping
|
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Proposal: Cross-platform
EPUBView(iOS + macOS)Status: Draft
Targets: iOS 15+, macOS 12+
Scope: API surface and architecture
Motivation
The current EPUB navigator is built around
EPUBNavigatorViewController,EPUBNavigatorViewModel, and a UIKit-onlyPaginationView.Over time, the EPUB rendering implementation evolved beyond a generic pagination container. EPUB-specific concerns such as reading preferences and settings resolution, Readium CSS integration, decorations, editing actions, selection handling, location and viewport tracking, resource preloading, JavaScript coordination, and web content lifecycle management are currently implemented across the EPUB navigator stack, including
EPUBNavigatorViewController, navigator models,PaginationView, and supporting rendering components.As a result, EPUB rendering behavior does not have a single owning abstraction. Responsibilities are distributed across multiple layers, making the rendering pipeline more difficult to reason about, test, and reuse independently from the existing navigator implementation.
This proposal introduces
EPUBView, a reusable cross-platform rendering component that consolidates EPUB rendering responsibilities behind a dedicated view abstraction.The goal of this proposal is not to replace
EPUBNavigatorViewControlleror the existing Navigator APIs. Instead, it extracts rendering concerns into a reusable component that can be hosted byEPUBNavigatorViewController, embedded directly in custom applications, or exposed through SwiftUI.By separating reading semantics from platform rendering, the EPUB rendering stack becomes platform-agnostic. Since
WKWebViewprovides an equivalent API on iOS and macOS, most of the rendering infrastructure can be shared across platforms, enabling macOS support and a unified SwiftUI integration with minimal platform-specific code.Design Overview
Current Architecture
Current Architecture
EPUBNavigatorViewControllercoordinates both the navigator state and rendering layers. It owns anEPUBNavigatorViewModelresponsible for navigation and reading state, whilePaginationViewis responsible for rendering and pagination.EPUB-specific responsibilities such as preferences, settings resolution, decorations, JavaScript coordination, viewport tracking, editing actions, and content lifecycle management are distributed across these components and supporting rendering infrastructure.
As a result, EPUB rendering behavior does not have a single owning abstraction.
Proposed Architecture
EPUBNavigatorViewControllerEPUBViewEPUBEngineEPUBViewRendererEPUBViewLayoutThe engine owns reading behavior. The renderer and layout own presentation.
Rendering Strategy
The renderer is built on top of a custom
EPUBViewLayoutrather than platform-provided flow layouts.EPUBViewLayoutis implemented as a customUICollectionViewLayouton iOS and a customNSCollectionViewLayouton macOS. It encapsulates EPUB-specific pagination and positioning behavior while remaining independent from navigation and reading semantics.The layout supports:
offsetFirstPage)EPUBViewRendererusesEPUBViewLayoutas the platform rendering primitive, whileEPUBEngineremains unaware of layout implementation details.Components
EPUBNavigatorViewControllerEPUBViewEPUBEngineEPUBViewRendererEPUBViewLayoutEPUBViewRepresentableEPUBView
EPUBView is a reusable rendering component for EPUB content.
It can be hosted by EPUBNavigatorViewController, embedded directly into UIKit/AppKit applications, or wrapped by SwiftUI.
All APIs are
@MainActor.Usage Examples
Navigation
Preferences
JavaScript
Decorations
Selection
EPUBEngine
EPUBEngineis an internal, platform-agnostic kernel responsible for:The engine contains no platform UI dependencies and no direct knowledge of scrolling primitives.
EPUBViewRenderer
EPUBViewRendereris the boundary between the engine and platform UI.The engine issues logical rendering commands:
The renderer reports logical events:
Renderer Implementations
UICollectionView+EPUBViewLayoutNSCollectionView+EPUBViewLayoutThe renderer delegates layout and pagination behavior to
EPUBViewLayout.SwiftUI
The representable is a thin wrapper around
EPUBViewand uses a coordinator to bridge delegate events into SwiftUI state.Relationship with EPUBNavigatorViewController
EPUBNavigatorViewControllerremains the primary Navigator implementation and continues to expose the existing Navigator APIs.This proposal does not introduce a new navigation model and does not deprecate any existing Navigator interfaces.
Internally,
EPUBNavigatorViewControllermay host anEPUBViewinstance to provide rendering capabilities, but applications can continue using the navigator exactly as they do today.Benefits
All reactions