- Rename source module from RDReaderView to RDEpubReaderView - Move all source files from Sources/RDReaderView/ to Sources/RDEpubReaderView/ - Update podspec: RDReaderView.podspec -> RDEpubReaderView.podspec - Update Podfile, demo project, and CocoaPods config for new pod name - Delete old RDReaderView pod support files from ReadViewDemo/Pods - Add new RDEpubReaderView pod support files - Update documentation (API ref, architecture, UML, conventions, etc.) - Add FixedLayoutRotationTests - Update .gitignore: exclude .DS_Store, manual unpack backups, _ssoft-output
16 KiB
16 KiB
公开 API 参考手册
最后更新:2026-06-18
本文档列出 ReadViewSDK 所有公开 API 的完整签名、参数说明和使用方法。
1. RDEPUBReaderController — 入口控制器
文件:Sources/RDEpubReaderView/EPUBUI/RDEPUBReaderController.swift 及扩展
1.1 初始化
// EPUB 文件初始化
init(
epubURL: URL, // EPUB 文件路径
configuration: RDEPUBReaderConfiguration = .default, // 阅读配置
persistence: RDEPUBReaderPersistence? = nil, // 持久化实现
dependencies: RDEPUBReaderDependencies? = nil // 依赖注入
)
// 预构建 TextBook 初始化(如 .txt 文件)
init(
textBook: RDEPUBTextBook, // 预构建的文本书籍
bookIdentifier: String, // 书籍唯一标识
title: String, // 书籍标题
textFileURL: URL? = nil, // 原始文件路径
configuration: RDEPUBReaderConfiguration = .default,
persistence: RDEPUBReaderPersistence? = nil,
dependencies: RDEPUBReaderDependencies? = nil
)
1.2 公开属性
| 属性 | 类型 | 读写 | 说明 |
|---|---|---|---|
delegate |
RDEPUBReaderDelegate? |
读写 | 委托代理 |
configuration |
RDEPUBReaderConfiguration |
读写 | 阅读配置,设置后触发重新分页 |
currentLocation |
RDEPUBLocation? |
只读 | 当前阅读位置 |
currentPageNumber |
Int? |
只读 | 当前页码(1-based) |
currentSelection |
RDEPUBSelection? |
只读 | 当前文本选区 |
highlights |
[RDEPUBHighlight] |
只读 | 所有高亮标注 |
bookmarks |
[RDEPUBBookmark] |
只读 | 所有书签 |
annotations |
[RDEPUBAnnotation] |
只读 | 合并排序后的统一标注列表 |
tableOfContents |
[EPUBTableOfContentsItem] |
只读 | 目录树(嵌套结构) |
flattenedTableOfContents |
[RDEPUBReaderTableOfContentsItem] |
只读 | 扁平化目录列表 |
currentTableOfContentsItem |
RDEPUBReaderTableOfContentsItem? |
只读 | 当前所在目录项 |
1.3 导航方法
/// 重新加载书籍
func reloadBook()
/// 跳转到指定位置
func go(to location: RDEPUBLocation)
/// 跳转到指定页码(1-based)
/// - Returns: 是否跳转成功
@discardableResult
func go(toPageNumber pageNumber: Int, animated: Bool = false) -> Bool
/// 跳转到目录项(EPUBTableOfContentsItem)
@discardableResult
func go(toTableOfContentsItem item: EPUBTableOfContentsItem, animated: Bool = true) -> Bool
/// 跳转到目录项(RDEPUBReaderTableOfContentsItem)
@discardableResult
func go(toTableOfContentsItem item: RDEPUBReaderTableOfContentsItem, animated: Bool = true) -> Bool
/// 跳转到目录 href(支持 fragment,如 "chapter1.xhtml#section2")
@discardableResult
func go(toTableOfContentsHref href: String, animated: Bool = true) -> Bool
/// 跳转到指定高亮位置
@discardableResult
func go(toHighlightID id: String, animated: Bool = true) -> Bool
/// 跳转到指定书签位置
@discardableResult
func go(toBookmarkID id: String, animated: Bool = true) -> Bool
1.4 高亮方法
/// 添加高亮(使用当前选区或指定选区)
/// - Parameters:
/// - selection: 选区信息,nil 时使用 currentSelection
/// - color: 高亮颜色(十六进制),默认 "#F8E16C"
/// - note: 可选备注
/// - Returns: 创建的高亮对象,失败返回 nil
@discardableResult
func addHighlight(
from selection: RDEPUBSelection? = nil,
color: String = "#F8E16C",
note: String? = nil
) -> RDEPUBHighlight?
/// 添加标注(支持高亮和下划线样式)
@discardableResult
func addAnnotation(
from selection: RDEPUBSelection? = nil,
style: RDEPUBHighlightStyle,
color: String = "#F8E16C",
note: String? = nil
) -> RDEPUBHighlight?
/// 更新或插入高亮
@discardableResult
func upsertHighlight(_ highlight: RDEPUBHighlight) -> RDEPUBHighlight?
/// 删除高亮
@discardableResult
func removeHighlight(id: String) -> RDEPUBHighlight?
/// 更新高亮备注
@discardableResult
func updateHighlightNote(id: String, note: String?) -> RDEPUBHighlight?
/// 删除所有高亮
func removeAllHighlights()
/// 根据 ID 查找高亮
func highlight(withID id: String) -> RDEPUBHighlight?
1.5 书签方法
/// 添加书签(使用当前位置)
@discardableResult
func addBookmark(note: String? = nil) -> RDEPUBBookmark?
/// 切换书签状态(已存在则删除,不存在则添加)
@discardableResult
func toggleBookmark(note: String? = nil) -> RDEPUBBookmark?
/// 删除书签
@discardableResult
func removeBookmark(id: String) -> RDEPUBBookmark?
/// 根据 ID 查找书签
func bookmark(withID id: String) -> RDEPUBBookmark?
1.6 搜索方法
/// 开始搜索
func search(keyword: String)
/// 跳转到下一个匹配
/// - Returns: 是否有下一个匹配
@discardableResult
func searchNext() -> Bool
/// 跳转到上一个匹配
@discardableResult
func searchPrevious() -> Bool
/// 清除搜索
func clearSearch()
1.7 其他方法
/// 清除当前文本选区
func clearSelection()
/// 获取当前页面的语义摘要(调试用)
func nativeTextSemanticSummary() -> String?
2. RDEPUBReaderDelegate — 委托协议
文件:Sources/RDEpubReaderView/EPUBUI/RDEPUBReaderDelegate.swift
所有方法均有默认空实现,可按需实现。
public protocol RDEPUBReaderDelegate: AnyObject {
/// 书籍打开完成
func epubReader(_ reader: UIViewController, didOpen publication: RDEPUBPublication)
/// 阅读位置变化
func epubReader(_ reader: UIViewController, didUpdateLocation location: RDEPUBLocation)
/// 到达书籍末尾
func epubReaderDidReachEnd(_ reader: UIViewController)
/// 文本选区变化(nil 表示取消选中)
func epubReader(_ reader: UIViewController, didChangeSelection selection: RDEPUBSelection?)
/// 高亮列表变化
func epubReader(_ reader: UIViewController, didUpdateHighlights highlights: [RDEPUBHighlight])
/// 书签列表变化
func epubReader(_ reader: UIViewController, didUpdateBookmarks bookmarks: [RDEPUBBookmark])
/// 搜索结果更新
func epubReader(_ reader: UIViewController, didUpdateSearchResult result: RDEPUBSearchResult?)
/// 当前搜索匹配项变化
func epubReader(_ reader: UIViewController, didChangeCurrentSearchMatch match: RDEPUBSearchMatch?)
/// 当前目录项变化
func epubReader(_ reader: UIViewController, didUpdateCurrentTableOfContentsItem item: RDEPUBReaderTableOfContentsItem?)
/// 外部链接被点击
func epubReader(_ reader: UIViewController, didActivateExternalLink url: URL)
/// 是否允许打开外部链接(返回 false 拦截)
func epubReader(_ reader: UIViewController, shouldOpenExternalURL url: URL) -> Bool
/// 错误回调
func epubReader(_ reader: UIViewController, didFailWithError error: Error)
/// 配置顶部工具栏(自定义按钮等)
func epubReader(_ reader: UIViewController, configureTopToolView topToolView: RDEPUBReaderTopToolView)
}
3. RDEPUBReaderPersistence — 持久化协议
文件:Sources/RDEpubReaderView/EPUBUI/RDEPUBReaderPersistence.swift
public protocol RDEPUBReaderPersistence: AnyObject {
func loadLocation(for bookIdentifier: String) -> RDEPUBLocation?
func saveLocation(_ location: RDEPUBLocation, for bookIdentifier: String)
func loadBookmarks(for bookIdentifier: String) -> [RDEPUBBookmark]
func saveBookmarks(_ bookmarks: [RDEPUBBookmark], for bookIdentifier: String)
func loadHighlights(for bookIdentifier: String) -> [RDEPUBHighlight]
func saveHighlights(_ highlights: [RDEPUBHighlight], for bookIdentifier: String)
func loadReaderSettings() -> RDEPUBReaderSettings?
func saveReaderSettings(_ settings: RDEPUBReaderSettings)
}
默认实现 RDEPUBUserDefaultsPersistence 使用 UserDefaults 存储:
| 数据 | Key 格式 |
|---|---|
| 阅读位置 | ssreader.epub.location.{bookID} |
| 书签 | ssreader.epub.bookmarks.{bookID} |
| 高亮 | ssreader.epub.highlights.{bookID} |
| 全局设置 | ssreader.epub.settings |
4. RDEPUBReaderConfiguration — 配置模型
文件:Sources/RDEpubReaderView/EPUBUI/Settings/RDEPUBReaderConfiguration.swift
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
fontSize |
CGFloat |
15 |
字体大小(pt) |
lineHeightMultiple |
CGFloat |
1.6 |
行距倍数 |
fontChoice |
RDEPUBReaderFontChoice |
.system |
字体选择(system/serif/rounded/monospaced) |
numberOfColumns |
Int |
1 |
每页列数(1 或 2) |
columnGap |
CGFloat |
20 |
列间距 |
displayType |
RDEpubReaderView.DisplayType |
.pageCurl |
翻页模式 |
landscapeDualPageEnabled |
Bool |
true |
横屏双页 |
showsTableOfContents |
Bool |
true |
显示目录 |
allowsHighlights |
Bool |
true |
允许高亮 |
showsSettingsPanel |
Bool |
true |
显示设置面板 |
reflowableContentInsets |
UIEdgeInsets |
(40,16,40,16) |
重排内容内边距 |
fixedContentInset |
UIEdgeInsets |
.zero |
固定布局内边距 |
theme |
RDEPUBReaderTheme |
.light |
阅读主题 |
darkImageAdjustmentEnabled |
Bool |
true |
暗色模式图片调整 |
darkImageBlendRatio |
CGFloat |
0.15 |
暗色图片混合比例(0-0.35) |
fixedLayoutFit |
RDEPUBFixedLayoutFit |
.page |
固定布局适配方式 |
fixedLayoutSpreadMode |
RDEPUBFixedLayoutSpreadMode |
.automatic |
固定布局跨页模式 |
textRenderingEngine |
RDEPUBTextRenderingEngine |
.dtCoreText |
文本渲染引擎 |
onDemandChapterWindowSize |
Int |
3 |
按需加载窗口大小(奇数,3-15) |
metadataParsingConcurrency |
Int |
CPU 核心数 | 后台解析并发数 |
jumpSessionPolicy |
RDEPUBJumpSessionPolicy |
.default |
远距跳转策略 |
allowedExternalURLSchemes |
Set<String> |
["https"] |
允许的外部 URL 协议 |
requiresExternalLinkConfirmation |
Bool |
true |
外部链接需确认 |
allowsInspectableWebViews |
Bool |
false |
WebView 可调试 |
enablesVerboseWebViewLogging |
Bool |
false |
WebView 详细日志 |
计算属性:
chapterWindowRadius: Int— 内存缓存窗口半径(onDemandChapterWindowSize / 2)
5. 翻页容器协议
文件:Sources/RDEpubReaderView/ReaderView/RDEpubReaderViewProtocols.swift
5.1 RDEpubReaderPageProvider(推荐)
@objc public protocol RDEpubReaderPageProvider: NSObjectProtocol {
/// 总页数
func numberOfPages(in readerView: RDEpubReaderView) -> Int
/// 返回指定页的视图
/// - Parameters:
/// - index: 页码索引(0-based)
/// - reusableView: 可复用的旧视图(可能为 nil)
func readerView(_ readerView: RDEpubReaderView, viewForPageAt index: Int, reusableView: UIView?) -> UIView
/// 页面标识符(用于缓存去重)
@objc optional func pageIdentifier(in readerView: RDEpubReaderView, index: Int) -> String?
/// 顶部工具栏视图
@objc optional func readerViewTopChrome(_ readerView: RDEpubReaderView) -> UIView?
/// 底部工具栏视图
@objc optional func readerViewBottomChrome(_ readerView: RDEpubReaderView) -> UIView?
}
5.2 RDEpubReaderDelegate
@objc public protocol RDEpubReaderDelegate: NSObjectProtocol {
/// 页面变化回调
func pageNum(readerView: RDEpubReaderView, pageNum: Int)
/// 屏幕方向即将变化
@objc optional func readerViewOrientationWillChange(readerView: RDEpubReaderView, isLandscape: Bool)
}
5.3 RDEpubReaderPageNavigating
public protocol RDEpubReaderPageNavigating: AnyObject {
/// 当前页码
var currentPage: Int { get }
/// 重新加载所有页面
func reloadPages()
/// 跳转到指定页
func transition(to page: Int, animated: Bool)
}
5.4 RDEpubReaderDataSource(遗留)
@objc public protocol RDEpubReaderDataSource: NSObjectProtocol {
func pageCountOfReaderView(readerView: RDEpubReaderView) -> Int
func pageContentView(readerView: RDEpubReaderView, pageNum: Int, containerView: UIView?) -> UIView
func pageIdentifier(readerView: RDEpubReaderView, pageNum: Int) -> String?
@objc optional func topToolView(readerView: RDEpubReaderView) -> UIView?
@objc optional func bottomToolView(readerView: RDEpubReaderView) -> UIView?
}
通过 RDEpubReaderLegacyDataSourceAdapter 自动适配到 RDEpubReaderPageProvider。
6. 数据模型速查
6.1 RDEPUBLocation
public struct RDEPUBLocation: Codable, Equatable {
public var bookIdentifier: String? // 书籍标识
public var href: String // 章节文件路径
public var progression: Double // 章节内进度(0.0-1.0)
public var lastProgression: Double? // 上次进度(用于恢复方向)
public var fragment: String? // 片段 ID(如 #section1)
public var rangeAnchor: RDEPUBTextRangeAnchor? // 文本范围锚点
}
6.2 RDEPUBBookmark
public struct RDEPUBBookmark: Codable, Equatable, Identifiable {
public let id: String // 唯一标识
public let bookIdentifier: String?
public let location: RDEPUBLocation
public let chapterTitle: String?
public let note: String?
public let createdAt: Date
}
6.3 RDEPUBHighlight
public struct RDEPUBHighlight: Codable, Equatable, Identifiable {
public let id: String
public let bookIdentifier: String?
public let location: RDEPUBLocation
public let text: String // 高亮文本内容
public let style: RDEPUBHighlightStyle // .highlight / .underline
public let color: String // 十六进制颜色
public let note: String?
public let rangeInfo: String? // CoreText 选区范围信息
public let createdAt: Date
public var uiColor: UIColor { ... } // 计算属性
}
6.4 RDEPUBAnnotation
public struct RDEPUBAnnotation: Codable, Equatable, Identifiable {
public let id: String
public let bookIdentifier: String?
public let kind: RDEPUBAnnotationKind // .bookmark / .highlight / .underline
public let location: RDEPUBLocation
public let text: String?
public let rangeInfo: String?
public let chapterTitle: String?
public let createdAt: Date
public var bookmark: RDEPUBBookmark? { ... } // kind == .bookmark 时有值
public var highlight: RDEPUBHighlight? { ... } // kind == .highlight/.underline 时有值
}
6.5 RDEPUBSelection
public struct RDEPUBSelection: Equatable {
public let bookIdentifier: String?
public let location: RDEPUBLocation
public let text: String // 选中文本
public let rangeInfo: String? // CoreText 选区范围
public let createdAt: Date
}
6.6 EPUBPage / EPUBChapterInfo
public struct EPUBPage: Equatable {
public let spineIndex: Int
public let chapterIndex: Int
public let pageIndexInChapter: Int
public let totalPagesInChapter: Int
public let chapterTitle: String
public let fixedSpread: EPUBFixedSpread?
}
public struct EPUBChapterInfo: Equatable {
public let spineIndex: Int
public let title: String
public let pageCount: Int
}
6.7 RDEPUBSearchResult / RDEPUBSearchMatch
public struct RDEPUBSearchResult: Equatable {
public let keyword: String
public let matches: [RDEPUBSearchMatch]
}
public struct RDEPUBSearchMatch: Equatable {
public let spineIndex: Int
public let progression: Double
public let previewText: String
public let rangeAnchor: RDEPUBTextRangeAnchor?
}