NSFetchedResultsController 和搜索 - Return 多个和单个部分?

NSFetchedResultsController and Searching - Return multiple and single sections?

编辑:

感谢 pbasdf 帮我解决了这个问题。

固定码:

   lazy var fetchedResultsController = self.getFetchedResultsController()
    var sectionKeyPath: String? = #keyPath(Object.sectionKey)
    var searchPredicate: NSCompoundPredicate?
   
    // MARK: - Return FRC:
    private func getFetchedResultsController() -> NSFetchedResultsController<Object> { // var fetchedResultsController:
        print("Lazy: getFetchedResultsController()")
        let fetchRequest: NSFetchRequest<Object> = Object.fetchRequest()
        fetchRequest.predicate = searchPredicate
        
        let sortByKey = NSSortDescriptor(key: #keyPath(Object.sectionKey), ascending: true)
        let sortByName = NSSortDescriptor(key: #keyPath(Object.name), ascending: true)
        
        fetchRequest.sortDescriptors = [sortByKey, sortByName]
        fetchRequest.fetchBatchSize = 20
        
        let fetchedResultsController = NSFetchedResultsController(
            fetchRequest: fetchRequest,
            managedObjectContext: coreDataStack.managedContext,
            sectionNameKeyPath: sectionKeyPath ?? nil,
            cacheName: nil)
        
        fetchedResultsController.delegate = self
        return fetchedResultsController
    }
    
    private func refreshFRC() {
        fetchedResultsController = getFetchedResultsController() // Reset FRC
        do {  // Load Data:
            try fetchedResultsController.performFetch()
        } catch let error as NSError {
            print("Fetching error: \(error), \(error.userInfo)")
        }
    }

这为您提供了带有可选谓词和 sectionNameKeyPath 的 FRC。然后您可以根据需要进行设置,然后使用 refreshFRC() 设置更改。


我正在使用 NSFetchedResultsController 将搜索添加到 table 视图。 我的目标:

我有工作代码。我可以根据我的 sectionKey 让 table 做这两项,我只是不知道如何在同一个构建中做这两项。

这是正常行为吗?我正在尝试通过更改 FRC 的 sectionNameKeyPath 和 sortDescriptors 来做一些不可能的事情?或者我只是错过了什么?

private func getFetchedResultsController() -> NSFetchedResultsController<Object> {
        let fetchRequest: NSFetchRequest<Object> = Object.fetchRequest()
        
        let sortByKey = NSSortDescriptor(key: #keyPath(Object.sectionKey), ascending: true)
        let sortByName = NSSortDescriptor(key: #keyPath(Object.name), ascending: true)
        
        switch sectionKeyPath {
        case nil:
            fetchRequest.sortDescriptors = nil
            fetchRequest.fetchBatchSize = 20
        default:
            fetchRequest.sortDescriptors = [sortByKey, sortByName]
            fetchRequest.fetchBatchSize = 20
        }
        fetchRequest.sortDescriptors = [sortByKey, sortByName]
        fetchRequest.fetchBatchSize = 20
        
        let fetchedResultsController = NSFetchedResultsController(
            fetchRequest: fetchRequest,
            managedObjectContext: coreDataStack.managedContext,
            sectionNameKeyPath: sectionKeyPath ?? nil,
            cacheName: nil)
        fetchedResultsController.delegate = self
        return fetchedResultsController
    }

我也很好奇对整个 viewController 使用单个 FRC 是否更好,或者为整个对象列表创建一个 FRC 是否更好,而第二个仅用于搜索何时激活?


func updateSearchResults(for searchController: UISearchController) {
    let searchBar = searchController.searchBar
    searchBar.barStyle = .default
    
    switch searchBar.text?.count {
    case nil:
        searchPredicate = nil
        sectionKeyPath = #keyPath(Object.sectionKey)
        tableView.reloadData()
    case 0:
        searchPredicate = nil
        sectionKeyPath = #keyPath(Object.sectionKey)
        tableView.reloadData()
    default:
        sectionKeyPath = nil
        guard let searchText = searchBar.text else { return }
        setSearchPredicate(search: searchText)
    }
    fetchFRC()
    tableView.reloadData()
} // End: updateSearchResults()

func fetchFRC() {
    do {
        try fetchedResultsController.performFetch()
    } catch let error as NSError {
        print("Fetching error: \(error), \(error.userInfo)")
    }
}

根据评论:

  1. updateSearchResults 代码中 fetchFRC 之前,您需要 re-call getFetchedResultsController;和
  2. 您需要将结果分配给视图控制器中定义的 fetchedResultsController 变量。