⚠️2023年7月6日,维基媒体对他们的维基百科 API / 移动内容服务引入了一个破坏性更改,这导致该框架中的requestArticle功能失效。

WikipediaKit · Swift 的 API 客户端框架

维基百科 API功能强大,但入门并不容易。

使用 WikipediaKit,可以轻松构建搜索和显示维基百科内容的应用程序,而无需担心原始 API。 WikipediaKit 不会暴露所有选项和端点,而是为构建阅读器应用程序提供对最有趣部分的便捷访问。 WikipediaKit 带有观点和态度——但这就是重点!

WikipediaKit 框架使用 Swift 编写,没有第三方依赖项,并且可以在 macOS、iOS、watchOS 和 tvOS 上运行。

安装

Swift Package Manager(首选)

可以使用 Swift Package Manager 将 WikipediaKit 添加到您的 Xcode 项目中。

Carthage

您可以使用 Carthage 来安装和更新 WikipediaKit。

手动

WikipediaKit.xcodeproj 拖放到您的应用程序项目中,并在应用程序项目的构建设置中添加 WikipediaKit 嵌入式框架。

用法

入门

Wikipedia 类将您的应用程序连接到维基百科的 API。 您可以通过查询新创建的 Wikipedia 实例来搜索、获取文章和列出附近的地方……

let wikipedia = Wikipedia()

……或者使用 shared 单例实例

let wikipedia = Wikipedia.shared

在执行任何其他操作之前,请确保添加您的电子邮件地址

WikipediaNetworking.appAuthorEmailForAPI = "appauthor@example.com"

WikipediaKit 将使用此电子邮件地址和您应用程序的 bundle 信息来生成和发送 User-Agent 标头。 这将使用每次 API 请求向维基百科的服务器标识您的应用程序,这是 API 指南的要求。

当您发出第一个 API 请求时,User-Agent 标头会打印到您的 Xcode 控制台中。 它看起来类似于这样

User-Agent: ExampleApp/1.0 (com.example.ExampleApp; appauthor@example.com) WikipediaKit/1.0

请在发布您的应用程序之前仔细检查 User-Agent 标头是否正确。

返回类型和异步网络

所有 Wikipedia 方法的返回类型都是标准的 URLSessionTask

let language = WikipediaLanguage("en")

let searchSessionTask = Wikipedia.shared.requestOptimizedSearchResults(language: language, term: "Soft rime") { (searchResults, error) in
    // This code will be called asynchronously
    // whenever the results have been downloaded.
    // …
}

可以像这样取消 URLSessionTask

searchSessionTask.cancel()

有关更多信息,请参见 URLSessionTask 文档。

语言

WikipediaLanguage 具有语言代码、本地化名称、本名,有时还有变体(例如,zh-hans 表示简体中文,zh-hant 表示繁体中文)。

// French language, localized name for German, no variant
let l = WikipediaLanguage(code: "fr",
                          localizedName: "Französisch", // FR in DE
                          autonym: "Français") // FR in FR

WikipediaKit 附带维基百科语言及其本名的列表。 这使您可以通过传递语言代码来初始化 WikipediaLanguage。 请注意,如果您使用此简写方法,则本地化名称将为英语。

let language = WikipediaLanguage("fr")
// code: "fr", localizedName: "French", autonym: "Français"

搜索

像这样搜索维基百科——例如,用英语搜索术语“Soft rime

let language = WikipediaLanguage("en")

let _ = Wikipedia.shared.requestOptimizedSearchResults(language: language, term: "Soft rime") { (searchResults, error) in

    guard error == nil else { return }
    guard let searchResults = searchResults else { return }

    for articlePreview in searchResults.items {
        print(articlePreview.displayTitle)
    }
}

searchResults 是一个 WikipediaSearchResults 对象。

搜索批处理大小(分页搜索结果)

要为查询加载更多搜索结果,只需为相同的 language:term: 启动另一个搜索,并将先前的 WikipediaSearchResults 对象作为 existingSearchResults: 参数传递。

默认批处理大小为 15,但可以通过在 maxCount 参数中传递不同的数字来更改。

搜索方法

有两种受支持的搜索方法 (WikipediaSearchMethod) 可以在维基百科上搜索文章。 您可以将它们传递给 requestSearchResults(method:language:term:)

为了获得更好的搜索结果质量, 使用 requestOptimizedSearchResults(language:term:),它不采用 method: 参数(请参见上面的示例)。 这将使用 .prefix 搜索,然后在搜索词的结果很少或没有结果时回退到 .fullText 搜索。

您可以使用 minCount: 参数调整触发回退 .fullText 搜索之前的最小结果数。

搜索缩略图大小

可以在可选的 imageWidth: 参数中调整 WikipediaArticlePreview 的图像 URL 的所需最大像素宽度。

搜索缓存

搜索会自动缓存,直到应用程序退出(请参见下面的缓存部分)。

文章预览

WikipediaArticlePreview 对象代表搜索结果项。 它们类似于完整的文章,但仅包含文章文本的摘录。

可以通过您的 WikipediaFormattingDelegate 格式化 displayTitledisplayText

文章

更新:自 WikipediaKit 3.0 以来,此方法使用新的维基百科 REST API。 重写是一个使 WikipediaKit 现代化的好机会,并返回 Result<WikipediaArticle, WikipediaError> 类型。

像这样加载关于英文“Soft rime”的文章

let language = WikipediaLanguage("en")

let _ = Wikipedia.shared.requestArticle(language: language, title: "Soft rime") { result in
    switch result {
    case .success(let article):
      print(article.displayTitle)
      print(article.displayText)
    case .failure(let error):
      print(error)
    }
}

可以通过您的 WikipediaFormattingDelegate 格式化 displayTitledisplayText

维基百科文章带有一个目录,存储在 WikipediaTOCItem 数组中。 可以在您的 WikipediaFormattingDelegate 中格式化节标题。

要查询给定文章的其他可用语言,请在您的 Wikipedia 实例上使用 requestAvailableLanguages(for:) 调用,传递现有文章。

文章会自动缓存,直到应用程序重新启动(请参见下面的缓存部分)。

附近搜索

此搜索模式返回特定位置周围的地理标记文章。 传入要搜索的坐标(纬度和经度)

let language = WikipediaLanguage("en")

let _ = Wikipedia.shared.requestNearbyResults(language: language, latitude: 52.4555592, longitude: 13.3175333) { (articlePreviews, resultsLanguage, error) in

    guard error == nil else { return }
    guard let articlePreviews = articlePreviews else { return }

    for a in articlePreviews {
        print(a.displayTitle)
        if let coordinate = a.coordinate {
            print(coordinate.latitude)
            print(coordinate.longitude)
        }
    }
}

特色文章

requestFeaturedArticles(language:date:) 查询从维基百科的官方分析中获取特定日期最受欢迎的文章列表。

请注意:3.0 之前的 WikipediaKit 版本使用来自旧维基百科 API 的原始数据来实现此功能。 新(当前)的实现使用与官方维基百科应用程序相同的新 API,该 API 似乎会过滤文章,去除可能令人反感的内容。

let language = WikipediaLanguage("en")

let dayBeforeYesterday = Date(timeIntervalSinceNow: -60 * 60 * 48)

let _ = Wikipedia.shared.requestFeaturedArticles(language: language, date: dayBeforeYesterday) { result in
    switch result {
    case .success(let featuredCollection):
	    for a in featuredCollection.mostReadArticles {
	        print(a.displayTitle)
	    }
    case .failure(let error):
      print(error)
    }
}

图像元数据

要查找给定大小的给定维基百科图像的 URL,请使用此调用

let language = WikipediaLanguage("en")

// You can pass multiple images here.
// Make sure to limit the number somehow
// because the API server will bail out
// if the query URL gets too long.

let urls = ["https://en.wikipedia.org/wiki/File:Raureif2.JPG"]

let _ = Wikipedia.shared.(language: language, urls: urls, width: 1000) { (imagesMetadata, error) in
    guard error == nil else { return }
    for metadata in imagesMetadata {
	    print(metadata.url) // URL for 1000px width version
	    print(metadata.description)
	    print(metadata.license)
	  }
}

您可以指定图像 ID,而不是 urls: 参数; 在这种情况下,ids: 参数将为 ["File:Raureif2.JPG"]

委托

WikipediaKit 带有几个委托协议,可帮助您跟踪状态、过滤和格式化。

网络委托

WikipediaNetworking.sharedActivityIndicatorDelegate = MyActivityIndicatorDelegate.shared

设置 WikipediaNetworkingActivityDelegate 以在网络操作开始和停止时接收 start()stop() 调用。

格式化委托

Wikipedia.sharedFormattingDelegate = MyFormattingDelegate.shared

WikipediaArticleWikipediaArticlePreview 类具有 displayTitledisplayText 属性。

您可以在 WikipediaFormattingDelegate 中解析和重新格式化文章文本、标题和目录,然后再进行缓存。

class MyFormattingDelegate: WikipediaTextFormattingDelegate {

    static let shared = MyFormattingDelegate()

    func format(context: WikipediaTextFormattingDelegateContext, rawText: String, title: String?, language: WikipediaLanguage, isHTML: Bool) -> String {
        // Do something to rawText before returning…
        return rawText
    }
}

缓存

缓存会在(处理和格式化之后)自动发生,用于搜索结果和文章。 WikipediaKit 使用简单的 NSCache 实例。

还有自动的 NSURLCache,由服务器的缓存标头控制。 您可以修改 Wikipedia.maxAgeInSeconds 中包含的 API 响应的缓存持续时间标头。

随机文章

像这样请求一个随机 WikipediaArticlePreview 对象数组

Wikipedia.shared.requestRandomArticles(language: self.language, maxCount: 8, imageWidth: 640) {
    (articlePreviews, language, error) in

    guard let articlePreviews = articlePreviews else { return }

    for article in articlePreviews {
        print(article.displayTitle)
    }
}

WikipediaKit 具有此便捷功能,可一次获取一个随机 WikipediaArticlePreview

Wikipedia.shared.requestSingleRandomArticle(language: self.language, maxCount: 8, imageWidth: 640) {
    (article, language, error) in

    guard let article = article else { return }

    print(article.displayTitle)
}

如果 maxCount 大于 1,则来自 API 查询的剩余结果将缓冲在共享的 WikipediaRandomArticlesBuffer 对象中,并将通过每次后续调用 requestSingleRandomArticle 逐个返回。 仅当没有剩余的缓冲随机文章或查询语言更改时,才会触发新的网络请求。

关于

WikipediaKit 由 Frank Rausch 创建。

© 2017–22 Raureif GmbH / Frank Rausch

许可证

MIT 许可证;请阅读此存储库中的 LICENSE 文件。

免责声明

本项目与官方维基百科项目或维基媒体基金会无关。

商标

Wikipedia® 是维基媒体基金会(一家非营利组织)的注册商标。