Reeeed:来自 feeeed 的阅读器模式

Screen recording of the Reader Mode for iPhone

Reeeed 是阅读器模式的 Swift 实现:你给它一个网页文章的 URL,它会提取内容——没有导航或其他任何冗余信息——并以标准格式显示给你。它比加载完整的网页更快、更一致且更少干扰。你可以传递给 Reeeed 一个 URL,并获得简单的 HTML 来显示。或者你可以使用包含所有功能的 SwiftUI ReeeederView,它会为你处理一切。

Screenshot of the Reader Mode on Mac

功能特性

安装

  1. 在 Xcode 的菜单中,点击 File → Swift Packages → Add Package Dependency...
  2. 粘贴此仓库的 URL:https://github.com/nate-parrott/reeeed

或者,在你的 Package.swift 中手动添加依赖项:.package(url: "https://github.com/nate-parrott/reeeed", from: "1.1.0")

用法

最简单的实现:ReeeederView

对于最简单的集成,只需呈现包含所有功能的 ReeeederView,就像这样

import SwiftUI
import Reeeeder

struct MyView: View {
    var body: some View {
        NavigationLink("Read Article") {
            ReeeederView(url: URL(string: "https://www.nytimes.com/2022/09/08/magazine/book-bans-texas.html")!)
        }
    }
}

ReeeederView 也支持额外的选项字典

public struct ReeeederViewOptions {
    public var theme: ReaderTheme // Change the Reader Mode appearance
    public var onLinkClicked: ((URL) -> Void)?
}

更灵活的实现

你可以使用 Reeeeder 直接获取文章 HTML

import Reeeeder
import WebKit
...
Task {
    do {
        let result = try await Reeeed.fetchAndExtractContent(fromURL: url, theme: options.theme)
        DispatchQueue.main.async {
            let webview = WKWebView()
            webview.load(loadHTMLString: result.styledHTML, baseURL: result.baseURL)
            // Show this webview onscreen
        }
    } catch {
        // We were unable to extract the content. You can show the normal URL in a webview instead :(
    }   
}

如果你有更具体的需求——也许想自己获取 HTML,或者将提取的文章 HTML 片段包装在你自己的模板中——这是操作方法。根据需要自定义代码

Task {
    // Load the extractor (if necessary) concurrently while we fetch the HTML:
    DispatchQueue.main.async { Reeeed.warmup() }
    
    let (data, response) = try await URLSession.shared.data(from: url)
    guard let html = String(data: data, encoding: .utf8) else {
        throw ExtractionError.DataIsNotString
    }
    let baseURL = response.url ?? url
    // Extract the raw content:
    let content = try await Reeeed.extractArticleContent(url: baseURL, html: html)
    guard let extractedHTML = content.content else {
        throw ExtractionError.MissingExtractionData
    }
    // Extract the "Site Metadata" — title, hero image, etc
    let extractedMetadata = try? await SiteMetadata.extractMetadata(fromHTML: html, baseURL: baseURL)
    // Generated "styled html" you can show in a webview:
    let styledHTML = Reeeed.wrapHTMLInReaderStyling(html: extractedHTML, title: content.title ?? extractedMetadata?.title ?? "", baseURL: baseURL, author: content.author, heroImage: extractedMetadata?.heroImage, includeExitReaderButton: true, theme: theme)
    // OK, now display `styledHTML` in a webview.
}

它是如何工作的?

所有用于从页面提取文章的出色库,例如 MercuryReadability,都是用 Javascript 编写的。所以 reeeed 打开一个隐藏的 webview,加载其中一个解析器,然后使用它来处理 HTML。一个页面的完整、混乱的 HTML 输入,然后——就像魔法一样——只有内容 返回。你获得一致、简单的 HTML,并且速度很快。

当然,这些库并非完美无缺。如果你给它们一个不是文章的页面——或者一篇混乱的文章——你将一无所获。在这种情况下,reeeed 将回退到显示完整的网页。

更新 Postlight Parser (前身为 Mercury) JS

上次更新于 2022 年 9 月 18 日 (v2.2.2)

  1. Sources/Reeeed/JS/mercury.web.js 文件替换为从 项目仓库 下载的新文件
  2. 确保演示应用程序正常工作。

我想要改进的地方