Swift中NSFetchRequest的多个NSPerdicate?

fgw7neuy  于 2023-04-04  发布在  Swift
关注(0)|答案(3)|浏览(65)

目前,我有一个简单的NSFetchRequest和一个关联的NSPerdicate。然而,我希望有一种方法可以附加多个 predicate 。我在Objective C中看到过例子,但没有Swift的例子。
您是否可以定义一个NSPerdicate的列表,或者以某种方式将多个NSPerdicate对象附加到单个NSFetchRequest?
谢谢!

cgh8pdjw

cgh8pdjw1#

您可以使用“NSCompoundPredicate”。例如:

let converstationKeyPredicate = NSPredicate(format: "conversationKey = %@", conversationKey)
let messageKeyPredicate = NSPredicate(format: "messageKey = %@", messageKey)
let andPredicate = NSCompoundPredicate(type: NSCompoundPredicateType.AndPredicateType, subpredicates: [converstationKeyPredicate, messageKeyPredicate])
request.predicate = andPredicate

可以改为“AndPredicateType”或“OrPredicateType”

zynd9foi

zynd9foi2#

Swift 4更新

let predicateIsNumber = NSPredicate(format: "isStringOrNumber == %@", NSNumber(value: false))
let predicateIsEnabled = NSPredicate(format: "isEnabled == %@", NSNumber(value: true))
let andPredicate = NSCompoundPredicate(type: .and, subpredicates: [predicateIsNumber, predicateIsEnabled])

//check here for the sender of the message

let fetchRequestSender = NSFetchRequest<NSFetchRequestResult>(entityName: "Keyword")
fetchRequestSender.predicate = andPredicate

最新Swift版本变化为:

`NSCompoundPredicateType.AndPredicateType` replaced by `NSCompoundPredicate.LogicalType.and`

希望对你有帮助!
谢谢

6ojccjat

6ojccjat3#

对于SwiftUI @FetchRequest。
以下是如何动态设置获取请求的 predicate 。首先,我在SwiftUI视图中拥有的属性:

@FetchRequest(
    sortDescriptors: [NSSortDescriptor(keyPath: \Pokemon.id, ascending: true)],
    animation: .default
) private var pokedex: FetchedResults<Pokemon>

@State var searchText = ""
@State var filterByFavorites = false

var compoundPredicate: NSPredicate {
    var predicates: [NSPredicate] = []
    
    // Add search predicate
    if !searchText.isEmpty {
        predicates.append(NSPredicate(format: "name CONTAINS[c] %@", searchText))
    }
    
    // Add favorite filter predicate
    if filterByFavorites {
        predicates.append(NSPredicate(format: "favorite == %d", true))
    }
    
    // Combine predicates
    return NSCompoundPredicate(andPredicateWithSubpredicates: predicates)
}

请注意,此时我并没有在fetch请求中设置任何 predicate 。还要注意,使这一切工作的部分是compoundPredicate计算属性。我从一个空的predicates数组开始,然后检查我的searchText,如果条件为真,则附加适当的 predicate 。然后检查我的filterByFavorites属性,并执行相同的操作。
好了,现在是body var中使其工作的代码。我不会发布我的整个视图,因为大部分都是无关紧要的,但这里是我添加列表视图的地方,它显示了我的pokedex获取的结果:
编辑:我之前的方法使用这个过滤器(如下所示)来评估列表中的每个项目,并使用compoundPredicate只显示那些匹配的口袋妖怪,但我意识到lorem ipsum(见回答评论),这是一种效率低下的方法,而且它不允许列表以我想要的方式动画。我将展示两种解决方案。
旧溶液:

List(pokedex.filter { compoundPredicate.evaluate(with: $0) }) { pokemon in
    ...
}
.searchable(text: $searchText, prompt: "Find a Pokemon")
.autocorrectionDisabled()

新解决方案:

List(pokedex) { pokemon in
    ...
}
.searchable(text: $searchText, prompt: "Find a Pokemon")
.autocorrectionDisabled()
.onChange(of: searchText) { _ in
    pokedex.nsPredicate = compoundPredicate
}
.onChange(of: filterByFavorites) { _ in
    pokedex.nsPredicate = compoundPredicate
}

因此,我没有使用旧解决方案中的过滤器,而是使用这两个onChange修饰符来观察searchTextfilterByFavorites属性的更改,然后直接将compoundPredicate应用于pokedex获取的结果。
在视图的其他地方,我有一个按钮,用户可以点击它来在true和false之间切换filterByFavorites

相关问题