Ember:原生且具可及性的 Hacker News 閱讀器(iOS)
Ember: 原生且具可及性的 Hacker News 閱讀器(iOS)
Ember 是一款開源的 SwiftUI Hacker News 閱讀器,支援 iOS、iPadOS 與 macOS,優先考慮可及性與原生效能,且不依賴任何第三方套件。
Ember:原生且具可及性的 Hacker News 閱讀器(iOS)
Ember 為 Apple 平台上的 Hacker News 提供原生且可及的閱讀體驗
Ember 是一款使用 SwiftUI 為 iPhone、iPad 與 Mac 所打造的原生 Hacker News 閱讀器。它致力於提供平靜且快速的使用體驗,將可及性視為核心功能而非事後考量。此應用程式為開源專案,且在開發時不使用任何第三方相依套件,採用單一程式碼基礎,根據裝置自動調整版面——從 iPhone 的分頁列到 Mac 與 iPad 的三窗格布局皆能因應。
完整的可及性整合
Ember 將可及性作為首要考量,特別聚焦於色彩視覺與系統層級的整合。
不依賴顏色
為確保色盲使用者的可用性,Ember 絕不僅以顏色作為狀態指示。每一次狀態變更皆會搭配圖示、形狀或文字。例如:
- 積分與評論數 皆搭配 SF Symbols。
- 已閱讀狀態 以勾號表示。
- 選取狀態 以環形與勾號標示。
系統層級的調整
此應用程式提供專屬的色盲友善提示設定,若系統開啟「不以顏色區分」設定,則會自動啟用。其他可及性功能包括:
- VoiceOver 支援: 故事列與控制項使用具意義的標籤、提示與自訂動作,確保每篇故事能作為完整元素被朗讀。
- 動態字型(Dynamic Type): 排版與版面(包括評論縮排)會依系統文字大小自動調整。
- 減少動畫(Reduce Motion): 當系統啟用「減少動作」設定時,動畫與載入閃爍效果會被最小化。
- 底線連結: 評論中的連結可加底線,以在不依賴顏色的情況下保持可辨識性。
智慧上手指引
首次啟動時,Ember 會偵測系統的 VoiceOver、Reduce Motion、不以顏色區分、粗體文字與大字體設定,並自動將應用程式調整為相符的狀態,同時通知使用者所做的變更。
核心功能與使用者體驗
Ember 包含完整的 Hacker News 閱讀工具套件,旨在提升效率與離線使用能力。
內容與資訊管理
- 資訊來源存取: 使用者可透過固定的篩選列切換 Top、New、Best、Ask HN、Show HN 與 Jobs。
- 原生評論串: Ember 直接解析 Hacker News 的 HTML 成原生文字,支援斜體、區塊引言與程式碼區塊,而非使用 WebView。評論串可折疊,並以深度指示器顯示,且一次請求即可載入。
- 搜尋: 提供跨 Hacker News 的全文搜尋,並可依相關性或最新度排序。
- 閱讀追蹤: 已閱讀的故事會變暗,以協助使用者追蹤閱讀進度。
離線功能與持久化
- 已儲存的故事: 書籤儲存在裝置上,且可離線存取。
- 磁碟快取: 透過受限的 JSON 磁碟快取(
DiskCacheactor)將資訊來源、故事與評論串快取至磁碟。當網路不可用時,應用程式會自動使用此快取。
桌面整合
透過 Mac Catalyst,Ember 為 Mac 與大型 iPad 提供原生的三窗格版面,包含來源清單側邊欄、故事列表與討論視圖並排顯示。
技術架構
Ember 採用純 SwiftUI 堆疊構建,目標平台為 iOS 18。
技術堆疊
- UI 框架: 使用 SwiftUI,iPhone 使用
TabView,桌面/iPad 使用NavigationSplitView。 - 狀態管理: 使用 Observation 框架(
@Observable)作為視圖模型與資料存儲。 - 並行處理: 使用
async/await網路請求,搭配TaskGroup同時抓取資訊來源頁面。 - 持久化: 設定與閱讀狀態儲存於
UserDefaults,已儲存的故事與磁碟快取則使用 JSON 檔案。 - 排版字體: 內建的 Inter 可變字體用於閱讀文字,系統字體則用於中繼資料。
資料來源
- Hacker News Firebase API: 用於取得資訊來源、項目與使用者資料。
- Algolia HN Search API: 用於搜尋以及一次請求取得完整評論樹。
社群回饋與開發
在 Hacker News 上的社群討論凸顯了對可及性重視的讚賞,尤其來自色盲開發者的回應。
「身為色盲者(也是 iOS 開發者),每當看到有應用程式不僅依賴顏色提示時,我都感到非常興奮。」
使用者表示希望此應用程式能上架 App Store,並加入登入與發文功能。已有貢獻者開始提交 pull request,以實作 HN 登入、評論與回覆,讓此應用程式超越僅能閱讀的體驗。