可读性 (Readability)

一个 Swift 库,封装了 @mozilla/readability 并通用化了 Firefox 阅读器,用于增强网页以获得更好的阅读体验。 该库通过与 WKWebView 集成,提供了一种无缝的方式来检测、解析和显示来自任何网页的易于阅读的内容。

Language:Swift License:MIT Latest Release X

浅色 (light) 深色 (dark) 棕褐色 (sepia)

特性 (Features)

要求 (Requirements)

安装 (Installation)

swift-readability 可通过 Swift Package Manager 获得

.package(url: "https://github.com/Ryu0118/swift-readability", exact: "0.1.0")

用法 (Usage)

基本解析 (Basic Parsing)

您可以从 URL 或直接从 HTML 字符串解析文章。

从 URL 解析 (Parsing from a URL)

import Readability

let readability = Readability()
let result = try await readability.parse(url: URL(string: "https://example.com/article")!)

从 HTML 字符串解析 (Parsing from an HTML string)

import Readability

let html = """
<html>
    <!-- Your HTML content here -->
</html>
"""
let result = try await readability.parse(html: html)

使用 WKWebView 实现阅读模式 (Implementing Reader Mode with WKWebView)

swift-readability 提供 ReadabilityWebCoordinator,它准备 WKWebView 配置,并公开两个异步流:contentParsed(发出生成的阅读器 HTML)和 availabilityChanged(发出阅读器模式可用性更新)。 此配置使您的 WKWebView 能够检测网页何时适合阅读模式,生成易于阅读的 HTML 叠加层,并动态切换阅读模式。

import ReadabilityUI

let coordinator = ReadabilityWebCoordinator(initialStyle: ReaderStyle(theme: .dark, fontSize: .size5))
let configuration = try await coordinator.createReadableWebViewConfiguration()
let webView = WKWebView(frame: .zero, configuration: configuration)

// Process generated reader HTML asynchronously.
for await html in coordinator.contentParsed {
    do {
        try await webView.showReaderContent(with: html)
    } catch {
        // Handle the error here.
    }
}

// Monitor reader mode availability asynchronously.
for await availability in coordinator.availabilityChanged {
    // For example, update your UI to enable or disable the reader mode button.
}

ReaderControllable 协议 (ReaderControllable Protocol)

以下是 ReaderControllable 协议扩展提供的每个函数的使用示例。 由于 WKWebView 符合 ReaderControllable,您可以直接在 WKWebView 实例上调用这些方法。

警告 (Warning)

对阅读器样式(主题和字体大小)的更改仅在 Web 视图处于阅读模式时可用。

import ReadabilityUI

// Set the entire reader style (theme and font size)
try await webView.set(style: ReaderStyle(theme: .dark, fontSize: .size5))

// Set only the reader theme (supports sepia, light, and dark).
try await webView.set(theme: .sepia)

// Set only the font size
try await webView.set(fontSize: .size7)

// Show the reader overlay using the HTML received from the ReadabilityWebCoordinator.contentParsed(_:) event.
try await webView.showReaderContent(with: html)

// Hide the reader overlay.
try await webView.hideReaderContent()

// Determine if the web view is currently in reader mode.
let isReaderMode = try await webView.isReaderMode()

如果您正在使用 WKWebView 的 SwiftUI 包装库(例如 Cybozu/WebUI),但该库未公开 WKWebView 实例,您可以让任何具有 evaluateJavaScript 方法的对象符合 ReaderControllable。 例如

import WebUI
import ReadabilityUI

extension WebViewProxy: @retroactive ReaderControllable {
    public func evaluateJavaScript(_ javascriptString: String) async throws -> Any {
        let result: Any? = try await evaluateJavaScript(javascriptString)
        return result ?? ()
    }
}

通过使 WebViewProxy 符合 ReaderControllable,您可以从代理控制阅读器,例如

WebViewReader { proxy in
    WebView(configuration: configuration)
        .task {
            for await html in coordinator.contentParsed {
                if let url = proxy.url {
                    try? await proxy.showReaderContent(with: html)
                    try? await proxy.set(theme: .dark)
                    try? await proxy.set(fontSize: .size8)
                }
            }
        }
}

示例(与 SwiftUI 集成)(Example (Integrating with SwiftUI))

有关使用 Cybozu/WebUI 将 swift-readability 与 SwiftUI 集成的更详细实现,请参阅此存储库中提供的 示例

构建 (Build)

在构建 Swift Package 之前,请完成以下步骤

  1. 验证是否已安装 npm。
  2. 然后,运行 make bootstrap


如果您修改了 webpack-resources 文件夹中的源代码,请运行 npm run build

致谢 (Credits)

该项目利用了几个开源项目

此外,以下文件根据 Mozilla Public License, Version 2.0 (MPL 2.0) 分发