使用NSPredicate根据数组属性过滤CoreData项列表

问题描述 投票:0回答:1

上下文

我有一个称为“任务”的核心数据实体

''Task'与另一个名为'Tag'的实体有关系:@NSManaged public var tags: NSSet?该数据存储为:

public var tagsArray: [Tag] {
    let set = tags as? Set<Tag> ?? []

    return set.sorted {
        $0.wrappedTagTitle < $1.wrappedTagTitle
    }
}

我正在尝试根据任务列表包含某个标签(即标题为“学校”的基础)来对其进行过滤。

var fetchRequest: FetchRequest<Task>

init(tagFilterName: String) {
    let tag = Tag()
    tag.title = tagFilterName
    fetchRequest = FetchRequest<Task>(entity: Task.entity(), sortDescriptors: [], predicate: NSPredicate(format: "tagsArray CONTAINS %@", tag))
}

这是在父视图中初始化的:

FilteredScrollView(tagFilterName: "School")

(请使用init中的随意代码,我只是想了解我想做的事情。)

结果

就目前而言,这会在运行时崩溃。任何帮助将不胜感激。

core-data swiftui nspredicate
1个回答
0
投票

直接的问题是您正在调用Tag()创建一个新实例,该实例不调用指定的初始化程序。要创建新的Tag,您将需要使用Tag(context: NSManagedObjectContext)。您会因为尝试使用未正确初始化的对象而崩溃。

虽然这只是问题的一部分。如果您解决了该问题,则会解决崩溃问题,但结果将为零。另一个问题是您不应该为获取创建新的Tag。核心数据谓词在寻找完全匹配的内容–没有类似Equatable的东西,它不会在寻找其他具有相同标题的Tag。它会寻找那个确切的标签。但是由于您只是创建了该标签,并且由于该标签未连接到任何任务,因此您将获得零结果。 CONTAINS运算符将不匹配任何内容,因为没有Task包含您刚创建的Tag

[通过关系匹配属性值-在这种情况下,通过Tag.title关系匹配tagsArray-您的谓词看起来像]

NSPredicate(format: "any tagsArray.title = %@", tagFilterName)

[获取Task时,它要求任何Task,其中tagsArray关系的任何成员的值都等于tagFilterName

© www.soinside.com 2019 - 2024. All rights reserved.