使用CoreData将远程搜索结果与本地数据库连接

时间:2016-06-02 11:53:18

标签: ios objective-c swift uitableview core-data

假设我们有单个实体User的简单数据模型;显示用户的简单tableView_friends fetchedResultsController_friends - 朋友。

假设我们有搜索栏用于搜索服务中的所有(不仅是朋友)用户,并且对于每个键入的字符,我们都会向服务器执行搜索请求,这些请求以某种方式按字符过滤返回给用户对象。其中一些对象已经可以在本地数据库中。通过应用程序逻辑,我们真的必须永远将所有这些结果保存在本地数据库中(但是,我们可以,我们可以及时清除本地数据库);另一方面,如果我们将对某些搜索用户执行任何操作,我们必须存储此用户。我们希望使用tableView_search在其他fetchedResultsController_search中显示已搜索用户的列表。

问题:我应该对fetchedResultsController_friendsfetchedResultsController_search使用相同的上下文吗?如果不是,当我希望编辑已存在于数据库中并且可能已经在本地编辑的搜索用户时,如何处理情况?如果是,我如何设置fetchedResultsController_search的谓词(服务器为逐字符搜索执行自己的逻辑,可以更改),以显示与服务器完全相同的结果?

1 个答案:

答案 0 :(得分:1)

我们最近在我们的应用程序中实现了一个搜索功能,并遇到了类似的问题,我们在核心数据中有本地数据,也有我们API的远程数据。

我们有几个选择:

  1. 将数据保存到API中,从而将数据保存到API中 然后取出的结果控制器将完成其余的工作
  2. 自己管理数据的合并,你仍然可以在一定程度上使用NSFetchedResults控制器,但需要做更多的工作
  3. 除非需要(用户选择它),否则我们不想保存从API返回的所有信息,因此我们提出了一个适用于我们的应用程序的简单解决方案。这可能无法直接用于您的应用,您可能需要一个完全不同的解决方案或更改我们所做的一些事情以适应。

    首先,为了解释我们正在处理的内容,我们在核心数据中有一个包含大约25个属性的文章实体,API将文章对象作为具有相同数据的JSON数据返回。

    我们决定创建一个代表文章简单版本的类(只有足够的数据显示在列表视图中,稍后在API或核心数据中引用它),如下所示:

    class SearchResult: NSObject {
    
        var id:String?
        var title:String?
        var imageUrl:String?
        var url:String?
    
        // core data entity
        init(article:Article) {
            self.id = content.contentId
            self.title = content.title
            self.featuredImageURL = content.absoluteImagePath()
            self.urlAlias = content.urlAlias
            self.publishedAt = content.publishedAt
        }
    
        init(articleDictionary:NSDictionary) {
            self.id = articleDictionary.objectForKeyNotNull("id") as? String
            self.title = articleDictionary.objectForKeyNotNull("title") as? String
            self.url = articleDictionary.objectForKeyNotNull("url") as? String
    
            if let imageUrl = articleDictionary.objectForKeyNotNull("imageUrl") as? String {
                self.imageUrl = imageUrl
            }
        }
    }
    

    现在使用它,我们可以从核心数据结果或API结果中创建一次。我们的tableview数据源只是一个数组

    var dataSet = [SearchResult]()
    

    我们使用NSFectchResultsController委托方法在初始加载后从dataSet添加/删除/重新排序核心数据元素,当我们获取API数据时,我们将执行以下操作:

    dataSet = Array(Set(apiResponseArray + dataSet))
    

    这将从API中获取一组SearchResult项,将它们与当前结果集合并并删除重复项。转换为集合然后返回数组将为您提供一系列唯一结果,因为Set仅由唯一值组成。

    请参阅此reference,这应该有助于委托方法的工作方式