AlgoliaSearch-Helper-Swift 0.2

AlgoliaSearch-Helper-Swift 0.2

测试已测试
语言编程语言 SwiftSwift
许可证 MIT
发布上次发布2016年12月
SPM支持 SPM

Clément Le Provost 维护。



  • Algolia

Swift 版 Algolia 搜索助手

注意: 测试版本。除非发布到 1.0 版本,否则可能发生不兼容的变更。

这是基于 Algolia 的 Swift API 客户端搜索 API构建的 Swift 版 Algolia 搜索助手 库。

目录

  1. 概述
  2. 快速入门
  3. 搜索
  4. 高亮显示
  5. 其他功能

概述

理由

虽然 API 客户端涵盖了搜索 API 的所有功能集,但其主要目标是效率和简单性。它并不提供超过原始搜索请求的更多功能。

然而,在构建搜索 UI 时,尤其是在实时搜索环境下,通常需要进行更多工作。搜索助手通过专注于 搜索会话 管理来进一步帮助您。

功能

助手的核心是 Searcher 类,它管理给定索引上的搜索。它负责正确地 排序 接收到的结果(这些结果可能由于网络不可预测性而出现顺序颠倒)并进行 分页。还提供了操作 子集和精确化 的工具。

HighlightRenderer 类负责将搜索结果中的高亮文本转换为可显示的属性文本。

还提供了一些其他的各种实用工具。

注意: 搜索助手是 UI 无关的。 尽管某些功能(如高亮显示)仅在用户界面上下文中才有用,但助手没有依赖特定的 UI 框架。例如,它可以无差别地在 iOS 的 UIKit 或 macOS 的 AppKit 上使用。它的系统依赖性仅限于 Foundation (见下文)。

支持的平台

该库是用 Swift 编写的,但完全兼容 Objective-C。

它支持 API 客户端 所支持的所有平台(截至撰写时:iOS、macOS 和 tvOS)。

依赖项

此模块需要

快速入门

设置

  • 将 "AlgoliaSearch-Helper-Swift" 作为依赖项添加

    • CocoaPods:将 pod 'AlgoliaSearch-Helper-Swift', '~> 1.0' 添加到您的 Podfile

    • 不支持 Carthage。 想知道原因吗?

  • import AlgoliaSearchHelper 添加到您的源文件中。

注意:如果您希望使用 API 客户端的离线模式,请改用子规范 AlgoliaSearch-Helper-Swift/Offline

示例

一个不错的选择是我们在 Movie Search 示例 中进行了广泛的搜索辅助器使用。

搜索

基础知识

首先创建一个 Client 和一个 Index,就像使用裸 API 客户端一样

let client = Client(appID: "YOUR_APP_ID", apiKey: "YOUR_API_KEY")
let index = client.index(withName: "index_name")

然后创建一个以索引为目标的 Searcher;您通常在创建期间指定一个结果处理程序(尽管您可以稍后注册更多处理程序)

let searcher = Searcher(index: index, resultHandler: self.handleResults)

也接受闭包

let searcher = Searcher(index: index, resultHandler: { (results: SearchResults?, error: NSError?) in
    // Your code goes here.
})

当您调用其 search() 方法时,搜索器才会启动请求。当然,在您进行搜索之前,您将想要修改搜索查询

searcher.query.query = "paris"
searcher.query.numericFilters = ["stars>=4"]
searcher.search()

处理结果

搜索器将在每次请求后调用您的结果处理程序,并且在收到响应时(除非请求已被取消,例如,因为已经收到了更新的结果),除非请求已被取消(例如,因为更新的结果已经收到)。通常,您的结果处理程序将检查错误,将命中存储在某些数据结构中,然后重新加载您的 UI

func handleResults(results: SearchResults?, error: Error?) {
    guard let results = results else { return }
    self.hits = results.hits
    self.tableView.reloadData()
}

SearchResults 类是 API 返回的 JSON 响应的包装器。您始终可以通过 content 属性直接访问底层的 JSON。然而,您最可能需要的字段也通过类型属性公开,例如 hitsnbHits。您还可以通过以下方式获得便利访问器

  • 面值(facets(name:))和统计数据(《 facetStats(name:));
  • 高亮(highlightResult(at:path:))和片段结果(《 snippetResult(at:path:))
  • 排名信息(《 rankingInfo(at:))

请注意,响应中可能不存在每条信息;这取决于您的请求。

持续滚动

搜索器通过其 loadMore() 方法简化了持续滚动的实现。通过调用此方法,可以轻松获取下一页的结果。

注意,如果您使用持续滚动,则必须注意将命中数据追加到您内部的数据结构中,而不是删除它们。通常,使用 page 属性就足够了。

if results.page == 0 {
    self.hits = results.hits
} else {
    self.hits.append(contentsOf: results.hits)
}

何时应该调用 loadMore()?每当您的 UI 感觉需要获取更多数据时。请注意,为了提供平滑的滚动体验,在需要之前获取数据通常更明智。一个很好的指标是当您的表格视图或集合视图数据源被调用以获取接近目前可用的数据的单元格时。或者,您可以使用 iOS 10 中引入的 UICollectionView 数据源预获取。

loadMore() 方法可避免并发或不一致的调用。如果在已有请求发出时尝试调用它,它将忽略该调用。

分面

搜索器在每个分面下维护一个经过细化值的列表,在 refinements 属性中。通常,您不需要直接操作该属性;相反,您可以通过调用便利方法 hasFacetRefinement(name:value:)addFacetRefinement(name:value:)removeFacetRefinement(name:value:)toggleFacetRefinement(name:value:) 来操作。

搜索器还通过 disjunctiveFacets 属性跟踪哪些分面是析取的(OR);未列在此属性中的所有分面都视为合取的(AND)。

当触发搜索时,搜索器将根据细化项和合取/析取状态构建 facetFilters

注意: 您需要通过搜索查询的 facets 参数指定所有分面的列表。

注意: 搜索查询的 facetFilters 参数将被搜索器覆盖;任何手动指定的值都将丢失。

事件

Searcher 类产生新的请求时,它通过 NSNotificationCenter 发射通知以各个事件的生命周期

  • Searcher.SearchNotification 新请求触发时
  • Searcher.ResultNotification 成功接收响应时
  • Searcher.ErrorNotification 接收错误响应时

您可以订阅这些通知以对不同事件做出反应,而无需显式编写结果处理程序。

突出显示

HighlightRenderer 类负责解析高亮结果值(由搜索API在每条记录的 _highlightResults 属性中返回)并将它们渲染为富文本字符串(一个 NSAttributedString 实例)。

当您实例化一个高亮渲染器时,您指定一组将应用于高亮部分的 文本属性。例如,以下代码将给出真正难看的红色键黄高亮

let renderer = HighlightRenderer(highlightAttrs: [
    NSForegroundColorAttributeName: UIColor.red,
    NSBackgroundColorAttributeName: UIColor.yellow,
]

默认情况下,渲染器被设置为识别 <em> 标签,这是搜索API用于标记高亮的默认标签。但是,您可以很容易地将其覆盖为自定义值。 注意: 在此情况下,请确保它与搜索查询中(或您索引的默认值)的 highlightPreTaghighlightPostTag 的值相匹配!

renderer.preTag = "<mark>"
renderer.postTag = "</mark>"

设置渲染器后,渲染高亮仅涉及调用 render(text:)。真正的技巧是从JSON中检索高亮值……幸运的是,SearchResults 类使其变得容易

let searchResults: SearchResults = ... // whatever was received by the result handler
let index: Int = ... // index of the hit you want to retrieve
if let highlightResult = searchResults.highlightResult(at: index, path: "attribute_name") {
    if let highlightValue = highlightResult.value {
        let highlightedString = renderer.render(text: highlightValue)
    }
}

杂项

防抖

“防抖”是一个忽略过于频繁的事件的过程,只保留一组相邻事件中的最后一个。

Debouncer 类提供了一种通用的防抖调用的方法。当UI组件(如滑块)不断地触发更新时,它可以用来避免频繁地触发搜索请求,这很有用。