DocumentModel
包含与 TagModel
关系的标签。视图接收 selectedTag。谓词(作为 @Query 的一部分)应该过滤具有给定标签的文档。
let selectedTag = TagModel()
#Predicate<DocumentModel> { document in
document.tags.contains {
$0.tagID == selectedTag.tagID
}
}
谓词未构建,因为:无法转换为闭包结果类型“任何 StandardPredicateExpression”。
谓词宏扩展为:
Foundation.Predicate<DocumentModel>({ document in
PredicateExpressions.build_contains(
PredicateExpressions.build_KeyPath(
root: PredicateExpressions.build_Arg(document),
keyPath: \.tags
)
) {
PredicateExpressions.build_Equal(
lhs: PredicateExpressions.build_KeyPath(
root: PredicateExpressions.build_Arg($0),
keyPath: \.tagID
),
rhs: PredicateExpressions.build_KeyPath(
root: PredicateExpressions.build_Arg(selectedTag),
keyPath: \.tagID
)
)
}
})
完整错误消息:
无法将“PredicateExpressions.SequenceContainsWhere
、PredicateExpressions.Equal 、PredicateExpressions.KeyPath >>”类型的值转换为闭包结果类型“any StandardPredicateExpression”
Apple 开发人员文档 有使用
contains()
和比较字符串的示例代码:
let messagePredicate = #Predicate<Message> { message in
message.recipients.contains {
$0.firstName == message.sender.firstName
}
}
如何过滤包含选定标签的文档?
您不应该访问除
document
(传递给 #Predicate
的闭包参数)之外的任何其他属性。虽然 #Predicate
在技术上支持这一点(即宏可以扩展到某些结果),但 SwiftData 不支持。 SwiftData 只能与 StandardPredicateExpression
一起使用,而只有 some PredicateExpression
才可以。
不要使用闭包捕获
selectedTag
,而只使用闭包捕获 selectedTag.tagID
struct SomeView: View {
let selectedTag: TagModel
@Query var documents: [DocumentModel]
init(selectedTag: TagModel) {
self.selectedTag = selectedTag
let selectedTagID = selectedTag.tagID
_documents = Query(filter: #Predicate<DocumentModel> { document in
document.tags.contains {
$0.tagID == selectedTagID
}
})
}
...
}
你也可以直接在闭包的捕获列表中写入
selectedTagID = selectedTag.tagID
:
_documents = Query(filter: #Predicate<DocumentModel> { [selectedTagID = selectedTag.tagID] document in
document.tags.contains {
$0.tagID == selectedTagID
}
})