ReadViewSDK/.planning/codebase/ARCHITECTURE.md
2026-05-21 20:36:12 +08:00

155 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!-- refreshed: 2026-05-21 -->
# 架构概览
**分析日期:** 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`(基于 URLepub/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*