我正在使用sqlite作为底层存储的CoreData堆栈。我的架构看起来像这样:
图像可以包含多个标签,标签可以属于多个图像。我的用例是能够搜索与特定标签名称匹配的图像。标记的name属性已编入索引。
我在ViewController中使用FetchedResultsController来填充具有所需图像的CollectionView。最初我将谓词传递为nil但是在搜索时我需要显示相关结果,即与标签匹配的图像与指定的标签名称。下面是我的FetchedResultsController初始化方法。
func initialiseFetchedResultsControllerWith(_ predicate: NSPredicate) {
//If the FRC is already initialised then just change the predicate and fetch again
if fetchedResultsController != nil {
fetchedResultsController.fetchRequest.predicate = predicate
} else {
let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: "SMImage")
let timestampSortDescriptor = NSSortDescriptor(key: "timestamp", ascending: false)
fetchRequest.sortDescriptors = [timestampSortDescriptor]
fetchRequest.predicate = predicate
fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: DataStoreController.sharedController.managedObjectContext!, sectionNameKeyPath: nil, cacheName: nil)
fetchedResultsController.delegate = self
}
do {
try self.fetchedResultsController.performFetch()
} catch {
print("Error in fetching image obbject via FRC => \(error)")
}
}
我需要将一个谓词传递给FetchedResultsController来获取图像。我想到了两种方法:
获取objectIDs包含搜索字符串的所有SMTag,然后查询包含这些objectID的SMImages。
let fetchRequest = NSFetchRequest<NSManagedObjectID>(entityName: "SMTag")
fetchRequest.predicate = NSPredicate(format: "name contains[cd] %@", text)
fetchRequest.resultType = NSFetchRequestResultType.managedObjectIDResultType
var tagIDs: Array<NSManagedObjectID>? = nil
do {
tagIDs = try DataStoreController.sharedController.managedObjectContext!.fetch(fetchRequest)
} catch {
print("Error in retreiving tags with names = \(error)")
}
if tagIDs != nil {
predicate = NSPredicate(format: "tags IN %@", NSSet(array: tagIDs!))
}
此方法确实返回tagID但不返回任何图像。
另一种方法是使用谓词直接搜索SMTag的图像名称:
predicate = NSPredicate(format: "ANY tags.name contains[cd] %@", text)
如果你知道任何更好的方法,请建议。任何帮助表示赞赏。
答案 0 :(得分:0)
这两种方法都没有充分利用核心数据。你有多对多的关系,为什么不用呢?更好的方法是:
获取包含搜索字词的单个SMTag
。这与代码片段的第一部分非常相似,只是您将获取托管对象而不是对象ID。
使用images
上的SMTag
关系获取与该标记相关联的所有图片。如果您有SMTag
的自定义类,则类似fetchedTag.images
。如果没有,那就像fetchedTag.value(forKey:"images")
。