AlgoliaSearch-Helper-Offline-Swift 0.2

AlgoliaSearch-Helper-Offline-Swift 0.2

测试已测试
Lang语言 SwiftSwift
许可证 MIT
发布最后发布2016年9月
SPM支持 SPM

Clément Le Provost 维护。



  • Algolia

Swift 的 Algolia 搜索辅助程序

警告: 测试版。在版本 1.0 发布之前,可能会有不兼容的更改。

这是基于 Algolia 的 Swift API 客户端以及 Algolia 的 搜索 API构建的 Swift 搜索辅助程序库。

目录表

  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: 将以下代码添加到您的Podfile文件中:pod 'AlgoliaSearch-Helper-Swift', '~> 1.0'

    • Carthage不受支持。想知道为什么吗?

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

注意:如果您想使用API客户端的离线模式,请使用子模块 AlgoliaSearch-Helper-Swift/Offline

示例

可以从我们的电影搜索演示开始,它广泛使用了搜索助手。

搜索

基础

首先创建一个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 小部件持续更新时(例如滑块)。