# 架构概览 **分析日期:** 2026-05-21 ## 系统概述 本仓库包含一个 iOS **阅读 SDK**(`RDReaderView`)以及一个用于演示集成的 **Demo App**(`ReadViewDemo`)。Demo 通过 CocoaPods 以本地 `:path` 方式引入 SDK。 ```text ┌─────────────────────────────────────────────────────────────────────────┐ │ Demo App │ │ `ReadViewDemo/ReadViewDemo` │ │ - 列表展示内置 .epub/.txt → push `RDURLReaderController` │ └───────────────────────────────┬─────────────────────────────────────────┘ │ uses ▼ ┌─────────────────────────────────────────────────────────────────────────┐ │ Public SDK │ │ `Sources/RDReaderView` │ │ 入口控制器: │ │ - `RDURLReaderController`(基于 URL:epub/txt) │ │ - `RDEPUBReaderController`(EPUB + 外部 TextBook) │ │ 核心视图: │ │ - `RDReaderView`(仿真翻页 / 横向 / 纵向模式) │ └───────────────┬───────────────────────────┬─────────────────────────────┘ │ │ ▼ ▼ ┌───────────────────────────┐ ┌─────────────────────────────────────────┐ │ EPUBCore │ │ EPUBTextRendering │ │ `Sources/RDReaderView/ │ │ `Sources/RDReaderView/EPUBTextRendering`│ │ EPUBCore` │ │ - 从 .txt 构建 `RDEPUBTextBook` │ │ - 解析/解压 EPUB │ │ - 文本章节渲染/搜索 │ │ - spine/TOC/location 模型 │ └─────────────────────────────────────────┘ │ - 基于 WKWebView 分页 │ │ - 资源解析/寻址 │ └───────────────┬───────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────────────┐ │ EPUBUI │ │ `Sources/RDReaderView/EPUBUI` │ │ - 阅读器 UX:工具栏/主题/设置 │ │ - 默认持久化(UserDefaults) │ │ - 协调 parser + paginator + RDReaderView │ └─────────────────────────────────────────────────────────────────────────┘ ``` ## 组件职责 | 组件 | 职责 | 文件 | |---|---|---| | `RDURLReaderController` | 面向“URL 打开”的顶层入口;根据后缀路由 epub vs txt;当分页失败时回退为纯文本展示 | `Sources/RDReaderView/RDURLReaderController.swift` | | `RDEPUBReaderController` | 主阅读器控制器;协调解析/分页,连接 `RDReaderView`;管理阅读状态、选择/高亮/书签、工具视图等 | `Sources/RDReaderView/EPUBUI/RDEPUBReaderController.swift` | | `RDReaderView` | 分页容器视图,支持仿真翻页与滚动模式;通过 data source 获取页面视图并回调当前页变化 | `Sources/RDReaderView/RDReaderView.swift` | | `RDEPUBParser` | 负责解析 `.epub`(container.xml + OPF);构建 manifest/spine/TOC;产出 `RDEPUBPublication` | `Sources/RDReaderView/EPUBCore/RDEPUBParser.swift` | | `RDEPUBPublication` | 对解析后的 publication 做只读封装(metadata/spine/TOC/资源解析、fixed-layout 判定等) | `Sources/RDReaderView/EPUBCore/RDEPUBPublication.swift` | | `RDEPUBPaginator` | 以 `WKWebView` 测量并生成分页信息(章节页范围、CFI 映射等) | `Sources/RDReaderView/EPUBCore/RDEPUBPaginator.swift` | | `RDEPUBReadingSession` | 阅读会话状态(当前章节/页、分页缓存、交互状态等),为 UI 层提供数据 | `Sources/RDReaderView/EPUBCore/RDEPUBReadingSession.swift` | | `RDEPUBReaderPersistence` | 阅读器持久化协议(位置/设置/书签/高亮等),默认实现使用 UserDefaults | `Sources/RDReaderView/EPUBUI/RDEPUBReaderPersistence.swift` | > 备注:实际类型与职责以代码为准;上表按文件职责做抽象总结。 ## 分层结构 **Demo App 层:** - 目的:展示集成方式与最小化书籍选择 UX。 - 位置:`ReadViewDemo/ReadViewDemo` - 依赖:本地 path 的 `RDReaderView` pod、UIKit。 **SDK UI 层(Reader UX):** - 目的:阅读器控制器 UX + 设置持久化 + 工具视图。 - 位置:`Sources/RDReaderView/EPUBUI` - 依赖:`EPUBCore`、`EPUBTextRendering`、`RDReaderView`。 **SDK View 层(分页容器):** - 目的:页面呈现模式(翻页/滚动)与手势/工具栏显示控制。 - 位置:`Sources/RDReaderView/RDReaderView.swift`、`Sources/RDReaderView/RDReaderFlowLayout.swift` - 依赖:UIKit。 **SDK Core 层(EPUB 解析/分页/状态):** - 目的:解析 EPUB 结构、资源寻址、分页计算、导航状态。 - 位置:`Sources/RDReaderView/EPUBCore` - 依赖:Foundation、WebKit(分页/导航)、ZIPFoundation(解压;通过 Podspec 依赖)。 **SDK 文本渲染层:** - 目的:为纯文本输入构建分页结构并提供渲染/搜索能力。 - 位置:`Sources/RDReaderView/EPUBTextRendering` - 依赖:UIKit/Foundation(以及通过 Podspec 依赖的 DTCoreText 相关能力)。 ## 数据流 ### 主路径(通过 URL 打开书籍) 1. Demo 选择文件并 push reader(`ReadViewDemo/ReadViewDemo/ViewController.swift`)。 2. `RDURLReaderController` 根据扩展名分发(`Sources/RDReaderView/RDURLReaderController.swift`)。 3. 对 EPUB:`RDEPUBReaderController` 开始加载,解析 publication,并为当前视口执行分页(`Sources/RDReaderView/EPUBUI/RDEPUBReaderController.swift`)。 4. 分页由 `RDEPUBPaginator`(`WKWebView` 测量)生成 `EPUBPage` / `EPUBChapterInfo` 等快照,供 `RDReaderView` 渲染(`Sources/RDReaderView/EPUBCore/RDEPUBPaginator.swift`、`Sources/RDReaderView/EPUBCore/RDEPUBReadingSession.swift`)。 5. `RDReaderView` 展示页面并输出页切换回调(`Sources/RDReaderView/RDReaderView.swift`)。 ### 次路径(打开纯文本文件) 1. `RDURLReaderController` 使用 `RDPlainTextBookBuilder` 构建 `RDEPUBTextBook`,分页尺寸/样式来自 `RDEPUBReaderConfiguration`(`Sources/RDReaderView/RDURLReaderController.swift`、`Sources/RDReaderView/EPUBTextRendering/RDPlainTextBookBuilder.swift`)。 2. `RDEPUBReaderController` 以 “external TextBook” 模式运行,复用相同的阅读器 UX 与持久化链路(`Sources/RDReaderView/EPUBUI/RDEPUBReaderController.swift`)。 **状态管理:** - 内存态主要由 `RDEPUBReadingSession` 与 `RDEPUBReaderController` 维护。 - 默认持久化为 UserDefaults(`RDEPUBUserDefaultsPersistence`,见 `Sources/RDReaderView/EPUBUI/RDEPUBReaderPersistence.swift`)。 ## 入口点 **SDK:** - `RDURLReaderController`:URL 入口,封装 epub/txt 分支(`Sources/RDReaderView/RDURLReaderController.swift`)。 - `RDEPUBReaderController`:可直接打开 epub URL,或读取已构建的 `RDEPUBTextBook`(`Sources/RDReaderView/EPUBUI/RDEPUBReaderController.swift`)。 - `RDReaderView`:可复用的分页视图(`Sources/RDReaderView/RDReaderView.swift`)。 **Demo:** - UIKit 生命周期(`ReadViewDemo/ReadViewDemo/AppDelegate.swift`、`ReadViewDemo/ReadViewDemo/SceneDelegate.swift`)。 ## 架构约束 - **平台:** iOS 15+(`RDReaderView.podspec` 中 `s.platform = :ios, "15.0"`)。 - **视口耦合:** 分页与视口大小/insets 强耦合,视口变化会触发重新分页(`Sources/RDReaderView/EPUBUI/RDEPUBReaderController.swift`)。 - **WebKit 依赖:** 可重排 EPUB 的分页使用离屏、非持久化的 `WKWebView`(`Sources/RDReaderView/EPUBCore/RDEPUBPaginator.swift`)。 ## 错误处理 **策略:** URL 入口采用“尽量可用”的 fail-soft 体验;Reader Controller 提供可见的 loading/error UI。 **模式:** - URL 入口在文本分页失败时回退为 `UITextView`(`Sources/RDReaderView/RDURLReaderController.swift`)。 - Parser 通过 `RDEPUBParserError` 抛出类型化错误(`Sources/RDReaderView/EPUBCore/RDEPUBModels.swift`)。 ## Evidence(关键证据) 检查过的关键文件: - `RDReaderView.podspec` - `Podfile` - `ReadViewDemo/ReadViewDemo.xcworkspace/contents.xcworkspacedata` - `ReadViewDemo/ReadViewDemo.xcodeproj/project.pbxproj` - `ReadViewDemo/ReadViewDemo/AppDelegate.swift` - `ReadViewDemo/ReadViewDemo/SceneDelegate.swift` - `ReadViewDemo/ReadViewDemo/ViewController.swift` - `Sources/RDReaderView/RDURLReaderController.swift` - `Sources/RDReaderView/RDReaderView.swift` - `Sources/RDReaderView/EPUBUI/RDEPUBReaderController.swift` - `Sources/RDReaderView/EPUBCore/RDEPUBParser.swift` - `Sources/RDReaderView/EPUBCore/RDEPUBPaginator.swift` - `Sources/RDReaderView/EPUBCore/RDEPUBPublication.swift` - `Sources/RDReaderView/EPUBCore/RDEPUBReadingSession.swift` --- *架构分析:2026-05-21*