如何在 Swift 中使用 UISearchBar 和 NSFetchedResultsController 在 Core Data 上一次获取多个实体?

Posted

技术标签:

【中文标题】如何在 Swift 中使用 UISearchBar 和 NSFetchedResultsController 在 Core Data 上一次获取多个实体?【英文标题】:How to fetch more than 1 Entity at once on Core Data using UISearchBar and NSFetchedResultsController in Swift? 【发布时间】:2016-05-16 23:49:10 【问题描述】:

大家好,我有一个使用 Core Data 和 NsFetchedResultsController 的应用程序,我正在使用 searchBar 来搜索 3 个实体中的属性。

问题自然是每个实体都有不同的属性。但我想使用来自用户的相同 searchBar 输入一次搜索所有 3 个实体。

所有 3 个实体都有一个属性“name”,其想法是搜索所有在“name”属性中包含 searchBar 字符串的实体。

到目前为止,我只能搜索 1 个实体,因为我正在使用此代码:

// MARK: - Fetched results controller
var fetchedResultsController: NSFetchedResultsController 
    if _fetchedResultsController != nil 
        return _fetchedResultsController!
    

    let fetchRequest = NSFetchRequest()
    // Edit the entity name as appropriate.

     let entity = NSEntityDescription.entityForName("Category", inManagedObjectContext: moc)
    fetchRequest.entity = entity

    // Set the batch size to a suitable number.
    fetchRequest.fetchBatchSize = 20

    // Edit the sort key as appropriate.
    let sortDescriptor = NSSortDescriptor(key: "index", ascending: true)

    fetchRequest.sortDescriptors = [sortDescriptor]

    // Edit the section name key path and cache name if appropriate.
    // nil for section name key path means "no sections".
    let aFetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: moc, sectionNameKeyPath: nil, cacheName: nil)
    aFetchedResultsController.delegate = self
    _fetchedResultsController = aFetchedResultsController

    do 
        try _fetchedResultsController!.performFetch()
     catch 
        // Replace this implementation with code to handle the error appropriately.
        // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
        //print("Unresolved error \(error), \(error.userInfo)")
        abort()
    

    return _fetchedResultsController!



// MARK: - Search
var searchController: UISearchController? = nil

func reloadFRC(predicate: NSPredicate?) 
    fetchedResultsController.fetchRequest.predicate = predicate
    performFecth()


//Delegate: UIsearchController
func updateSearchResultsForSearchController(searchController: UISearchController) 
    if let searchBarText = searchController.searchBar.text 
        var predicate: NSPredicate?
        if searchBarText != "" 
            predicate = NSPredicate(format: "name contains[cd] %@", searchBarText)
        
        self.reloadFRC(predicate)
    



//Delegate: UISearchBar
func searchBarTextDidEndEditing(searchBar: UISearchBar) 
    self.reloadFRC(nil)



//Configure Search
func configureSearch() 
    self.searchController = UISearchController(searchResultsController: nil)
    if let _searchController = self.searchController 
        _searchController.delegate = self
        _searchController.searchResultsUpdater = self
        _searchController.dimsBackgroundDuringPresentation = false
        _searchController.searchBar.delegate = self
        _searchController.searchBar.sizeToFit()
        _searchController.searchBar.barTintColor = Utils.colorFromHex(0x2FC5DA)
        _searchController.searchBar.tintColor = Utils.colorFromHex(0x585858)
        self.tableView.tableHeaderView = _searchController.searchBar
     else print("ERROR configuring _searchController in %@", #function)

那么,我该怎么做呢?

【问题讨论】:

【参考方案1】:

不再需要使用_fetchedResultsController,它几乎与所有 Swift 编码风格背道而驰。此外,您可以替换 nil 检查并改用 lazy 修饰符。您是否有特定的原因要使其成为 lazy 而不仅仅是正常初始化它?如果这是一个搜索屏幕,似乎 99.9% 的时间它都会被初始化。

现在谈谈您的实体问题。使所有 3 个实体都继承自一个父实体。此父实体将包含 name 属性。然后,您将获取父实体,它将正确搜索所有子实体。

您还可以通过为NSFetchedResultsController 初始化函数的.sectionNameKeyPath 传入entity.name 来按实体划分它们。如果你决定走这条路,你还需要按entity.name 排序,所以它知道如何对这些部分进行排序。

【讨论】:

所以我应该从所有 3 个实体中删除“名称”属性并放入父实体中?我不明白搜索如何从父实体访问对象名称。 如果属性被转移到搜索,我怎么能继续向每个实体添加对象?因为正如我所说,每个实体都有“名称”属性,用户需要在每个实体中创建对象。所以,如果我从 3 个实体中删除“名称”并放入父实体,我将如何在 3 个实体上添加工作?你明白我的意思吗? 子实体继承其父实体的所有属性。因此,为父实体定义的任何属性 (name) 也将为子实体定义。这在继承部分解释:developer.apple.com/library/mac/documentation/Cocoa/Conceptual/… 但我不明白如何编写所有这些代码。我创建了一个名为“搜索”的实体并将其设置为其他 3 个的父级。我再次生成了子类,但我不知道如何在代码中实现搜索功能。你能帮我@bsmith11 吗?

以上是关于如何在 Swift 中使用 UISearchBar 和 NSFetchedResultsController 在 Core Data 上一次获取多个实体?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Swift 中更改 UISearchBar 上的“取消”按钮的颜色

如何在swift 3中过滤UISearchBar中的数组模型

如何将 UiSearchBar 的背景颜色更改为黑色-SWIFT

UISearchbar 在 Swift 4 中使用 UItextfield

“Swift Core Data”如何向 UISearchBar 添加 Scope Bars? [关闭]

Swift iOS 8+ UISearchBar图标,占位符和文本居中