# Document Runtime iOS FFI 调用指南 ## 1. 概述 Document Runtime(zx_document_core)通过 UniFFI 生成 C-ABI 兼容的 Swift 绑定,嵌入 iOS 应用作为 `ZxDocumentRuntime.xcframework`。 Swift 层通过 uniffi 生成的 `zx_document.swift` 调用所有 Rust 功能。 --- ## 2. 架构 ``` ┌──────────────────────────────────────┐ │ iOS Swift │ │ zx_document.swift (uniffi 生成) │ │ ├─ buildDocumentInfo() │ │ ├─ parseMarkdown() │ │ ├─ extractPdfText() │ │ ├─ extractEpubChapterTexts() │ │ ├─ searchBlocks() / searchText() │ │ ├─ resolveNoteAnchors() │ │ ├─ startReadingSessionV2() │ │ ├─ pushHeartbeatV2() │ │ ├─ exportPending() / ackExported() │ │ └─ ... │ └──────────────┬───────────────────────┘ │ C-ABI (uniffi) ┌──────────────▼───────────────────────┐ │ Rust: zx_document_ffi │ │ lib.rs — #[uniffi::export] fns │ └──────────────┬───────────────────────┘ │ ┌──────────────▼───────────────────────┐ │ Rust: zx_document_core │ │ document / markdown / pdf / epub / │ │ search / anchors / events_v2 / ... │ └──────────────────────────────────────┘ ``` --- ## 3. 类型映射 ### 3.1 基础类型 | Rust | Swift | |------|-------| | `String` | `String` | | `u32` / `u64` | `UInt32` / `UInt64` | | `i64` | `Int64` | | `bool` | `Bool` | | `Vec` | `[T]` | | `Option` | `T?` | | `Result` | `throws` | ### 3.2 结构体 → Record ```rust #[derive(uniffi::Record)] pub struct DocumentInfo { ... } ``` ```swift // uniffi 生成 public struct DocumentInfo { public var materialId: String public var title: String public var materialType: MaterialType // ... } ``` ### 3.3 枚举 → Enum ```rust #[derive(uniffi::Enum)] pub enum MaterialType { Markdown, Text, Pdf, Image, Epub, Word, Excel, PowerPoint, Unknown } ``` ```swift public enum MaterialType { case markdown, text, pdf, image, epub, word, excel, powerPoint, unknown } ``` --- ## 4. 核心 API ### 4.1 文档解析 ```swift // 构建文档信息(文件类型检测 + 元数据提取) let info = try buildDocumentInfo( filePath: "/path/to/file.md", materialId: "mat-001", title: "My Document" ) // → DocumentInfo { materialType, pageCount, wordCount, epubChapterCount, ... } // Markdown 解析为块 let blocks = try parseMarkdown(markdown: "# Title\n\nContent") // → [DocumentBlock] // PDF 元数据 let pdfMeta = try readPdfMetadata(filePath: "/path/to/book.pdf") // → PdfMetadata { pageCount, title, author } // PDF 文本提取 let pages = try extractPdfText(filePath: "/path/to/book.pdf") // → [PdfPageText { pageNumber, text }] // EPUB 元数据 let epubMeta = try readEpubMetadata(filePath: "/path/to/book.epub") // → EpubMetadata { title, author, chapterCount } // EPUB 章节文本提取(HTML strip) let chapters = try extractEpubChapterTexts(filePath: "/path/to/book.epub") // → [EpubChapterText { chapterId, text }] ``` ### 4.2 搜索 ```swift // 搜索 Markdown 块 let results = searchBlocks(blocks: blocks, query: "keyword") // → [SearchResult { blockId, snippet, matchStart, matchEnd }] // 搜索纯文本 let textResults = searchText(content: text, query: "keyword") // → [SearchResult { lineNumber, ... }] ``` ### 4.3 锚点 ```swift let anchors = try resolveNoteAnchors( blocks: blocks, anchorHints: ["#heading-1", "#paragraph-2"] ) // → [NoteAnchor { anchorId, blockId, ... }] ``` ### 4.4 V2 阅读会话 ```swift // 开始会话 let sessionId = try startReadingSessionV2( material: ReadingMaterialRefV2(materialId: "mat-001"), timestampMs: Int64(Date().timeIntervalSince1970 * 1000) ) // 推送位置变更事件 try pushPositionChangedV2( sessionId: sessionId, position: ReadingPosition.markdown( blockId: "b1", scrollProgress: 0.5 ), timestampMs: nowMs() ) // 导出待上传事件 let (events, state) = exportPendingV2() // → ([BufferedReadingEventV2], EventBufferStateV2) // ACK 已上传事件 ackExportedV2(count: UInt32(events.count)) // 关闭会话 try closeReadingSessionV2(sessionId: sessionId, timestampMs: nowMs()) ``` --- ## 5. 错误处理 所有 FFI 函数返回 `Result`(UniFFI 映射为 Swift `throws`): ```swift do { let info = try buildDocumentInfo(filePath: path, materialId: id, title: title) // 使用 info } catch { print("Document Runtime error: \(error)") // error 是 Rust DocumentError 的 Display 字符串 } ``` 常见错误: - `IoError` — 文件不存在/无权限 - `ParseError` — 格式损坏/不支持的格式 - `MarkdownParseError` — Markdown 语法错误 --- ## 6. 线程安全 - Rust 层使用 `Mutex>` 保护全局状态(EventBuffer) - 所有 FFI 函数可从任意线程调用 - Swift 层应在主线程调用 UI 更新,后台线程调用 FFI --- ## 7. 性能建议 | 操作 | 建议 | |------|------| | `buildDocumentInfo` | 主线程调用(< 50ms),缓存结果 | | `extractPdfText` | 后台线程(可能耗时数秒) | | `parseMarkdown` | 任意线程(< 10ms) | | `searchBlocks` | 任意线程(< 10ms) | | `exportPendingV2` | 后台定时器(30s),主线程调用也可 | --- ## 8. 相关文档 - [V2 事件 Pipeline 架构](../ios-projects/docs/v2-event-pipeline.md)(ios-projects 仓库) - [Rust FFI 绑定更新流程](../ios-projects/docs/rust-ffi-update.md)(ios-projects 仓库) - [UniFFI UDL 编写规范](./uniffi-udl-spec.md) - [文件格式支持矩阵](./file-format-support-matrix.md)