Ember:面向 iOS 的原生、无障碍优先 Hacker News 阅读器
Ember 是一款使用 SwiftUI 构建的原生 Hacker News 阅读器,在 iPhone、iPad 和 Mac 上提供高性能、无障碍的使用体验。通过避免第三方依赖并使用原生渲染来展示线程化评论,Ember 为长篇技术讨论提供了“平静”的阅读体验,并进行了优化。
无障碍优先设计
Ember 将无障碍视为核心功能,而非可选附加项,特别关注色觉缺陷和系统级无障碍设置。
非颜色视觉提示
为确保色盲用户也能使用,Ember 从不单纯依赖颜色来传达状态。它实现了以下内容:
- 图标化: 点数和评论数量均配有 SF Symbols。
- 状态指示器: 已读状态使用对勾标记,选中状态使用环形和对勾。
- 显式提示: 当系统开启“区分颜色”时,自动启用的专用设置会在整个 UI 中添加非颜色指示器。
- 链接识别: 评论中的链接可以加下划线,以便在不依赖颜色的情况下仍然可辨认。
系统集成
Ember 深度集成 iOS 的无障碍框架:
- VoiceOver: 故事行和控件使用有意义的标签、提示和自定义操作,确保每篇故事被读取为单一连贯的元素。
- 动态文字(Dynamic Type): 排版随系统文字大小缩放,布局——包括评论缩进——会适配无障碍尺寸。
- 降低动画(Reduce Motion): 当系统开启“降低动画”设置时,动画和加载闪烁效果会被最小化。
- 自适应引导: 首次启动时,Ember 会检测系统的 VoiceOver、粗体文字和大字号设置,自动配置应用并通知用户所做的更改。
技术架构
Ember 使用面向 iOS 18 的现代 Apple 技术栈构建,并利用 Mac Catalyst 实现桌面支持。
核心技术栈
- UI 框架: 纯 SwiftUI。布局会根据水平尺寸类自适应:iPhone 使用
TabView,Mac 与 iPad 使用三列NavigationSplitView。 - 状态管理: 采用 Observation 框架(
@Observable)来管理视图模型和存储。 - 并发: 网络请求使用
async/await,并通过TaskGroup并行获取 feed 页面。 - 持久化:
UserDefaults管理设置和已读状态,受限的 JSON 磁盘缓存(DiskCacheactor)存储 feed 列表和评论树,以实现离线回退。
数据获取与渲染
Ember 结合两套主要 API 提供无缝体验:
- 官方 HN Firebase API: 用于获取 feed、条目和用户资料。
- Algolia HN Search API: 用于全文搜索以及一次性获取完整评论树。
为避免使用 WebView 的开销,Ember 使用自研的 HTML 解析器,将 Hacker News 的有限标签集(<p>、<i>、<b>、<a>、<pre><code>、<br>)直接转换为原生 AttributedString 块。
关键特性
- 完整 Feed: 通过固定的过滤栏可访问 Top、New、Best、Ask HN、Show HN 与 Jobs。
- 离线能力: 已收藏的故事会保存在设备上,已浏览的 feed 与评论线程会缓存到磁盘,离线时可自动回退。
- 跨平台布局: 在 Mac 与 iPad 上提供原生三窗格布局,包含来源列表侧栏、故事列表和讨论视图并排显示。
- 阅读优化: 应用使用 Inter 可变字体,配以舒适的行距和受限的行宽,以提升长线程的可读性。
- 用户资料: 可查看用户的 karma、加入日期以及最近的提交。
社区反馈与洞察
Hacker News 的用户强调了该应用的无障碍聚焦价值,一位色盲开发者表示他们“每次看到一个不依赖颜色提示的应用都感到兴奋”。
其他社区讨论聚焦于分发方式和功能对齐:
- 分发: 多位用户询问 App Store 上架或 TestFlight 访问情况,项目目前仍需用户使用 Xcode 与 XcodeGen 从源码构建。
- 功能请求: 社区对加入登录与发布功能表现出兴趣,建议使用 WebView 提取 Cookie 以便对 HN 接口进行身份验证。
- 对比: 用户将 Ember 与 Octal、Hackfeed 等其他阅读器进行比较,认为 Ember 的开源属性和无障碍重点是显著的差异化因素。
摘要
Ember 是一款开源、原生 SwiftUI 的 Hacker News 阅读器,支持 iOS、iPadOS 与 macOS,优先考虑无障碍和离线阅读,且不依赖任何第三方库。
标题
Ember:面向 iOS 的原生、无障碍优先 Hacker News 阅读器