BLResultsController 2.1.0

BLResultsController 2.1.0

Bell App LabBell App Lab维护。



 
依赖于
RealmSwift~> 10.0
BackgroundRealm~> 3.0
 


BLResultsController Version License

Platforms Swift support CocoaPods Compatible Carthage compatible SwiftPM compatible Twitter

BLResultsController

与普遍看法相反,BLResultsController并不是用于Realm的NSFetchedResultsController的替代品,哦不,它是更好的。

ResultsController接受一个Realm.Results并将其对象根据sectionNameKeyPath和第一个sortDescriptor划分为部分。然后它计算这些对象的相对位置并生成准备好传递给UITableViewUICollectionView的分区索引和IndexPath

但是没有在主线程上进行昂贵计算。没错,一切都是后台完成的,所以你的UI将保持像以前一样平滑和响应。

Realm.Results一样,ResultsController是一个活着的、自动更新的容器,只要你在它上面保持强引用,它就会继续通知你数据集的变化。你可以通过在你的控制器上调用setChangeCallback(_:)来注册接收这些更改。

对底层数据集的更改是在后台队列上计算的,因此UI线程不受ResultsController开销的影响。

注意:与Realm本身一样,ResultsController不是线程安全的。你应该只从主线程调用其大多数方法。

功能

  • 后台线程上计算一切。🏎
  • 没有保留对象,所以内存占用很小。👾
  • 计算分区索引标题。😲
  • 允许用户发起搜索。🕵️‍♀️🕵️‍♂️
  • 大多数方法返回时间复杂度为O(1)。😎
  • 文档完善。🤓
  • 经过充分测试。👩‍🔬👨‍🔬

规范

  • RealmSwift 10.0.0+
  • iOS 12+
  • tvOS 12+
  • macOS 10.12+
  • Swift 5.0+

BLResultsController同样使用了令人惊叹的BackgroundRealm。瞧瞧吧!

示例

ResultsController

在您的RealmObject子类上安装ResultsControllerElement协议

public final class Foo: Object, ResultsControllerElement
{
    //If your class doesn't have a unique identifier yet, do this
    public dynamic var resultsControllerId: String = UUID().uuidString
    
    //If it does, you can do this
    public var resultsControllerId: String {
        return <#id#>
    }
}

然后

import UIKit
import RealmSwift
import BLResultsController

class ViewController: UITableViewController {
    let controller: ResultsController<<#SectionType#>>, <#ElementType#>> = {
        do {
            let realm = <#instantiate your realm#>
            let keyPath = <#the key path to your Element's property to be used as a section#>
            return try ResultsController(
                realm: realm,
                sectionNameKeyPath: keyPath,
                sortDescriptors: [
                    SortDescriptor(keyPath: keyPath)
                ]
            )
        } catch {
            assertionFailure("\(error)")
            //do something about the error
        }
    }()

    override func viewDidLoad() {
        super.viewDidLoad()

        controller.setChangeCallback { [weak self] change in
            switch change {
            case .reload(_):
                self?.tableView.reloadData()
            case .sectionUpdate(_, let insertedSections, let deletedSections):
                self?.tableView.beginUpdates()
                insertedSections.forEach { self?.tableView.insertSections($0, with: .automatic) }
                deletedSections.forEach { self?.tableView.deleteSections($0, with: .automatic) }
                self?.tableView.endUpdates()
            case .rowUpdate(_, let insertedItems, let deletedItems, let updatedItems):
                self?.tableView.beginUpdates()
                self?.tableView.insertRows(at: insertedItems, with: .automatic)
                self?.tableView.deleteRows(at: deletedItems, with: .automatic)
                self?.tableView.reloadRows(at: updatedItems, with: .automatic)
                self?.tableView.endUpdates()
            }
        }
        
        controller.setFormatSectionIndexTitleCallback { (section, _) -> String in
            return section
        }
        
        controller.setSortSectionIndexTitles { (sections, _) in
            sections.sort(by: { $0 < $1 })
        }

        controller.start()
    }

    override func numberOfSections(in tableView: UITableView) -> Int {
        return controller.numberOfSections()
    }

    override func tableView(_ tableView: UITableView,
                            numberOfRowsInSection section: Int) -> Int
    {
        return controller.numberOfItems(in: section)
    }

    override func tableView(_ tableView: UITableView,
                            cellForRowAt indexPath: IndexPath) -> UITableViewCell
    {
        guard let cell = tableView.dequeueReusableCell(withIdentifier: <#identifier#>) else {
            fatalError("Did we configure the cell correctly on IB?")
        }
        <#code#>
        return cell
    }
    
    override func tableView(_ tableView: UITableView,
                            titleForHeaderInSection section: Int) -> String?
    {
        return controller.section(at: section)
    }
    
    override func sectionIndexTitles(for tableView: UITableView) -> [String]? {
        return controller.indexTitles()
    }
    
    override func tableView(_ tableView: UITableView,
                            sectionForSectionIndexTitle title: String,
                            at index: Int) -> Int
    {
        return controller.indexPath(forIndexTitle: title).section
    }
}

哗啦啦💥

安装

Cocoapods

pod 'BLResultsController', '~> 2.1.0'

然后将import BLResultsController添加到所需的位置。

Carthage

github "BellAppLab/BLResultsController" ~> 2.1.0

然后将import BLResultsController添加到所需的位置。

Swift包管理器

.package(url: "https://github.com/BellAppLab/BLResultsController.git", from: "2.1.0")

Git 子模块

cd toYourProjectsFolder
git submodule add -b submodule --name BLResultsController https://github.com/BellAppLab/BLResultsController.git

然后将 BLResultsController 文件夹拖入您项目的 Xcode 中。

作者

小铃铛应用程序实验室,[email protected]

贡献

查看 这里

致谢

许可证

BLResultsController 在 MIT 许可证下可用。更多详情,请参阅 LICENSE 文件。