Files
ReadViewSDK/Sources/RDReaderView/EPUBUI/ReaderController/RDEPUBReaderLoadCoordinator.swift
T
shenandshen 948004eed1 docs: 补充注释、修正过时文档、清理重复内容
源码注释:
- 为 ~60 个 Swift 文件补充缺失的 doc comment(file header、类型、属性、方法)
- 修正 4 处错误注释:翻页模式数量、搜索行为描述、手势识别器描述、悬空文档块

文档维护:
- 删除重复文档:WXRead/读书EPUB阅读器实现架构.md(与微信读书版完全一致)
- 合并重叠文档:阅读器规划.md → 阅读器功能开发计划.md(单一真值)
- 修正过时内容:所有文档中"四种翻页模式"→"三种",移除 horizontalCoverScroll
- 更新架构图:补齐 EPUBUI/ReaderController、Paging/、Typesetter/ 等子目录
- 更新 index.md 索引:新增开发计划和架构对比文档引用
2026-06-01 09:33:23 +08:00

94 lines
3.9 KiB
Swift

import Foundation
/// EPUB 阅读器加载协调器:负责 EPUB 文件的解析和出版物初始化。
///
/// 职责:
/// - 判断是否需要执行首次加载
/// - 后台解析 EPUB 文件并构建 Publication 模型
/// - 将解析结果应用到阅读器上下文并触发分页
final class RDEPUBReaderLoadCoordinator {
private unowned let context: RDEPUBReaderContext
init(context: RDEPUBReaderContext) {
self.context = context
}
/// 检查条件后启动首次加载,确保只执行一次且视图已布局。
func startInitialLoadIfNeeded() {
guard let controller = context.controller,
let readerView = context.readerView,
!controller.didStartInitialLoad,
readerView.bounds.width > 0,
readerView.bounds.height > 0 else {
return
}
controller.didStartInitialLoad = true
loadPublication()
}
/// 后台解析 EPUB 文件,加载书签、高亮和阅读位置,完成后回调主线程。
func loadPublication() {
guard let controller = context.controller else { return }
context.showLoading()
let loadToken = UUID()
context.paginationToken = loadToken
DispatchQueue.global(qos: .userInitiated).async { [weak controller] in
guard let controller else { return }
let parser = self.context.makeParser()
do {
try parser.parse(epubURL: controller.epubURL)
let publication = parser.makePublication()
let bookIdentifier = parser.metadata.identifier ?? controller.epubURL.lastPathComponent
let restoreLocation = controller.persistence?.loadLocation(for: bookIdentifier)
let bookmarks = controller.persistence?.loadBookmarks(for: bookIdentifier) ?? []
let highlights = controller.persistence?.loadHighlights(for: bookIdentifier) ?? []
DispatchQueue.main.async {
guard self.context.paginationToken == loadToken else { return }
self.context.runtime?.applyParsedPublication(
parser: parser,
publication: publication,
bookIdentifier: bookIdentifier,
restoreLocation: restoreLocation,
bookmarks: bookmarks,
highlights: highlights
)
}
} catch {
DispatchQueue.main.async {
guard self.context.paginationToken == loadToken else { return }
self.context.handle(error: error)
}
}
}
}
/// 将解析完成的出版物应用到上下文,设置书签/高亮/会话,并触发分页。
func applyParsedPublication(
parser: RDEPUBParser,
publication: RDEPUBPublication,
bookIdentifier: String,
restoreLocation: RDEPUBLocation?,
bookmarks: [RDEPUBBookmark],
highlights: [RDEPUBHighlight]
) {
guard let controller = context.controller else { return }
context.parser = parser
context.publication = publication
context.currentBookIdentifier = bookIdentifier
context.activeBookmarks = bookmarks
context.activeHighlights = highlights
context.readingSession = RDEPUBReadingSession(publication: publication)
context.readingSession?.transition(to: .loading)
controller.title = parser.metadata.title.isEmpty
? controller.epubURL.deletingPathExtension().lastPathComponent
: parser.metadata.title
controller.applyReaderViewConfiguration()
context.updateReaderChrome()
controller.delegate?.epubReader(controller, didOpen: publication)
context.runtime?.paginatePublication(restoreLocation: restoreLocation)
}
}