V1 → V2 兼容层
策略
V1 不删除,V2 新增独立模块。iOS 可逐步迁移。
V1 模块(保留 deprecated)
| 文件 |
状态 |
说明 |
events.rs |
#[deprecated] |
旧 ReadingEvent 类型 + push/export/clear |
reading_material.rs |
#[deprecated] |
旧 ReadingMaterialRef(仅 material_id) |
所有 V1 #[uniffi::export] 方法保留,确保现有 iOS V1 接入不中断。
V2 模块(新增)
| 文件 |
内容 |
reading_material.rs |
ReadingMaterialRefV2(camelCase, 8 fields) |
session_v2.rs |
ReadingSessionV2 + 5 statuses + lifecycle methods |
events_v2.rs |
ReadingEventV2 + EventBuffer (ack/failed/reload/state) |
time_tracker.rs |
ActiveTimeTracker(iOS 控制 tick) |
progress.rs |
ReadingPosition(camelCase + clamp) |
V1 vs V2 差异
| 维度 |
V1 |
V2 |
| material ref |
ReadingMaterialRef { material_id } |
ReadingMaterialRefV2 { 8 fields } |
| session |
无独立模型 |
ReadingSessionV2 + lifecycle |
| event_id |
无 |
UUID v4, 36 char |
| session_id |
无 |
UUID v4 |
| sequence |
无 |
u64 递增 |
| active_seconds |
累计/语义模糊 |
activeSecondsDelta 增量 |
| position |
snake_case |
camelCase + clamp 0~1 |
| buffer 管理 |
无 ack/failed |
export→ack/failed/reload 完整生命周期 |
| time tracker |
无 |
ActiveTimeTracker(iOS tick / pause / resume) |
| session recovery |
无 |
reload_stale_events_v2 + interrupted/failed |
iOS 迁移路径
Phase 1 (当前):
iOS 继续使用 V1 接入(V1 方法仍可用)
Phase 2:
iOS 实现 V2ReadingRuntimeAdapter(使用 V2 方法)
同时保留 V1ReadingRuntimeAdapter 作为 fallback
Phase 3:
全量切换到 V2
V1 接口留在代码中保持编译兼容
Phase 4 (未来):
确认所有端都切换到 V2 后,可移除 V1
active_seconds vs activeSecondsDelta
| V1 |
V2 |
active_seconds 语义模糊,可能是累计值 |
active_seconds_delta 每次 heartbeat 增量 |
| iOS 侧自己算 |
ActiveTimeTracker 计算,基于 timestamp 差值 |
| 无 clamp / 校验 |
maxDeltaSeconds=60,超出 clamp + warning |
FFI 接口对比
| V1 (deprecated) |
V2 |
push_reading_event(ReadingEvent) |
push_material_opened_v2 / push_heartbeat_v2 / ... |
export_pending_events() → Vec<ReadingEvent> |
export_pending_events_v2(limit, ts) → Vec<ReadingEventV2> |
clear_exported_events(count) |
ack_events_v2(eventIds) + mark_events_failed_v2(eventIds) |
| — |
reload_stale_events_v2() |
| — |
get_event_buffer_state_v2() |
验收