FirebaseResultsController
FirebaseResultsController 是一个用于管理附加到 Firebase 实时数据库的查询结果的控制器。
它提供了额外的过滤和排序功能,差异支持(使用 LCS 算法),以及实时内容更新。这些功能结合在一起,便于构建数据驱动的 UITableView。
示例
本项目包含一个简单的演示应用程序,演示如何使用 FirebaseResultsController 驱动一个 UITableViewController 实例。
先决条件
要运行示例项目,请克隆仓库,并首先从 Example 目录运行 pod install
。
您还需要创建一个 Firebase 账户,并按照指示创建一个演示项目。一旦您的演示项目在 Firebase 账户中创建完成,您需要下载项目中对应的 GoogleService-Info.plist
并将其添加到演示项目中。Firebase 框架在应用启动时会自动检测此文件,并相应地配置环境。
提示:您可以直接将您的 GoogleService-Info.plist
复制到 Example/FirebaseResultsController/
目录中,Xcode 项目应该会自动识别。
安装
FirebaseResultsController可通过CocoaPods获得。要安装它,只需将以下行添加到您的Podfile中
pod "FirebaseResultsController"
使用说明
FirebaseFetchRequest
要描述一个获取操作,您首先需要创建一个FirebaseFetchRequest。您可以通过 Firebase DatabaseQuery 实例来创建 FirebaseFetchRequest。数据库查询已经提供了过滤和排序的支持,但仅限于一定程度。如果内置行为不足以满足需求,您可以指定一个 NSPredicate,以及一个可以应用于最终获取数据的 NSSortDescriptor 数组。
let query: DatabaseQuery = ... // some Firebase query
let fetchRequest = FirebaseFetchRequest(query: query)
fetchRequest.predicate = ... // optional NSPredicate that is applied to fetched data
fetchRequest.sortDescriptors = ... // optional array of NSSortDescriptor's applied to fetched data
FirebaseResultsController
FirebaseResultsController是用于获取数据的主要类。您可以通过 FirebaseFetchRequest 创建它,并可选地在结果对象上进行 sectionNameKeyPath
返回分区名称。
let controller = FirebaseResultsController(fetchRequest: fetchRequest, sectionNameKeyPath: <optional key path>)
您至少必须调用一次performFetch()
以开始接收数据。之后,如果更改控制器获取请求中的谓词或排序描述符,您必须再次调用performFetch()
(即通过搜索栏进行过滤)。
controller.fetchRequest.predicate = ... // updated predicate
controller.fetchRequest.sortDescriptors = ... // updated sort descriptors
controller.performFetch() // reconfigures the controller for the updated fetch request
调用 performFetch()
将为指定的数据库查询附加观察者。这会自动为控制器的内容提供实时更新。要启用这些实时更新的差异,您需要指定一个changeTracker
,它是一个符合FirebaseResultsControllerChangeTracking
协议的对象。
controller.changeTracker = ... // object that conforms to FirebaseResultsControllerChangeTracking
例如
extension ViewController: FirebaseResultsControllerChangeTracking {
func controller(_ controller: FirebaseResultsController, didChangeContentWith changes: FetchResultChanges) {
tableView.beginUpdates()
// apply section changes
changes.enumerateSectionChanges { (section, sectionIndex, type) in
switch type {
case .insert:
self.tableView.insertSections(IndexSet(integer: sectionIndex), with: .fade)
case .delete:
self.tableView.deleteSections(IndexSet(integer: sectionIndex), with: .fade)
default:
break
}
}
// apply row changes
changes.enumerateRowChanges { (anObject, indexPath, type, newIndexPath) in
switch type {
case .insert:
tableView.insertRows(at: [newIndexPath!], with: .fade)
case .delete:
tableView.deleteRows(at: [indexPath!], with: .fade)
case .update:
self.configureCell(tableView.cellForRow(at: indexPath!)!, with: anObject)
case .move:
tableView.moveRow(at: indexPath!, to: newIndexPath!)
}
}
tableView.endUpdates()
}
}
组合结果(Beta)
您可以使用 ComposedFirebaseResultsController 来组合多个 FirebaseResultsController。
let controller1 = FirebaseResultsController(fetchRequest: fetchRequest1, sectionNameKeyPath: <optional key path>)
let controller2 = FirebaseResultsController(fetchRequest: fetchRequest2, sectionNameKeyPath: <optional key path>)
let controller3 = FirebaseResultsController(fetchRequest: fetchRequest3, sectionNameKeyPath: <optional key path>)
let controllers = [controller1, controller2, controller3]
let composedResultsController = ComposedFirebaseResultsController(controllers: controllers, composedQuery: <optional composed query>)
ComposedFirebaseResultsController 在内部控制器和外部聚合结果之间映射索引路径。它还暴露了与 FirebaseResultsController 相似的 API。
贡献
在您的自己的仓库中为项目创建一个分支。进行所有必要的修改,并创建一个带有添加或删除内容描述以及代码更改细节的pull request。如果获得批准,项目所有者将合并请求。
作者
Christian Gossain, [email protected]
许可证
FirebaseResultsController采用MIT许可证发布。详情见LICENSE。