当我们使用SwiftUI的@FetchRequest
属性包装器时,我们可以提供一个排序描述符数组来控制结果的顺序,但是我们也可以提供NSPredicate
来控制应显示哪些结果。谓词是简单的测试,该测试将应用于我们的Core Data实体中的每个对象——只有通过测试的对象才会包含在结果数组中。
NSPredicate
的语法不是您可以轻易猜到的,但实际上,您只会想要几种谓词,因此它并不像您想的那样糟糕。
要尝试一些谓词,请创建一个名为Ship
的新实体,该实体具有两个字符串属性:“name”和“universe”。
现在将ContentView.swift修改为:
import CoreData
import SwiftUI
struct ContentView: View {
@Environment(\.managedObjectContext) var moc
@FetchRequest(entity: Ship.entity(), sortDescriptors: [], predicate: nil) var ships: FetchedResults<Ship>
var body: some View {
VStack {
List(ships, id: \.self) { ship in
Text(ship.name ?? "Unknown name")
}
Button("Add Examples") {
let ship1 = Ship(context: self.moc)
ship1.name = "Enterprise"
ship1.universe = "Star Trek"
let ship2 = Ship(context: self.moc)
ship2.name = "Defiant"
ship2.universe = "Star Trek"
let ship3 = Ship(context: self.moc)
ship3.name = "Millennium Falcon"
ship3.universe = "Star Wars"
let ship4 = Ship(context: self.moc)
ship4.name = "Executor"
ship4.universe = "Star Wars"
try? self.moc.save()
}
}
}
}
现在,我们可以点击按钮,将一些样本数据注入Core Data,但是现在我们没有谓词。为了解决这个问题,我们需要用某种可以应用于我们的对象的测试谓词来代替nil
。
例如,我们可以要求来自 Star Wars 的船只,如下所示:
@FetchRequest(entity: Ship.entity(),
sortDescriptors: [],
predicate: NSPredicate(format: "universe == 'Star Wars'")
) var ships: FetchedResults<Ship>
如果您的数据包含引号,那将变得很复杂,因此更常见的是使用特殊的语法:“%@”表示“在此处插入一些数据”,并允许我们将数据作为谓词的参数而不是内联。
因此,我们可以这样写:
NSPredicate(format: "universe == %@", "Star Wars"))
除了==
之外,我们还可以使用诸如<
和>
之类的比较来过滤对象。例如,这将返回Defiant,Enterprise和Executor:
NSPredicate(format: "name < %@", "F")) var ships: FetchedResults<Ship>
%@
在后台做了很多工作,尤其是在将本机Swift类型转换为等效的Core Data时。例如,我们可以使用IN
谓词来检查 universe 是否是数组中三个选项之一,如下所示:
NSPredicate(format: "universe IN %@", ["Aliens", "Firefly", "Star Trek"])
我们还可以使用谓词来检查字符串的一部分,例如使用BEGINSWITH
和CONTAINS
这样的运算符。例如,这将返回所有以大写字母E开头的船:
NSPredicate(format: "name BEGINSWITH %@", "E"))
该谓词区分大小写;如果要忽略大小写,则需要对此进行修改:
NSPredicate(format: "name BEGINSWITH[c] %@", "e"))
CONTAINS[c]
的工作方式类似,除了可以从子字符串开始,它可以位于属性内的任何位置。
最后,您可以使用NOT
翻转谓词,以获得其常规行为的反函数。例如,这将查找所有以E开头的船舶:
NSPredicate(format: "NOT name BEGINSWITH[c] %@", "e"))
如果您需要更复杂的谓词,请使用AND
将它们连接起来以建立所需的尽可能多的精度,或者为Core Data添加导入并查看NSCompoundPredicate
——它使您可以从多个较小的谓词中构建一个谓词。
网友评论