SwiftData中如何使用带格式化字符串的NSPredicate实现带条件的实体查询?
SwiftData中如何使用带格式化字符串的NSPredicate实现带条件的实体查询?
嗨,我来帮你搞定这个SwiftData的查询问题!你其实已经找对方向了,SwiftData里的用法和Core Data逻辑非常相似,只是需要把NSPredicate关联到FetchDescriptor上就行,我给你调整一下代码:
首先,你原来的代码里已经创建了predicate,但没把它和FetchDescriptor绑定起来。在SwiftData中,FetchDescriptor专门用来定义查询的条件、排序等规则,我们只需要在初始化它的时候传入predicate参数就可以了。另外,我建议你用%K作为属性名的占位符,这是NSPredicate的规范写法,比直接拼接字符串\(attribute)更安全,能避免属性名解析错误的问题。
修改后的完整代码如下:
func fetchAllEntities<T>(with value: String, for attribute: String) throws -> [T] where T : PersistentModel { // 用%K指定属性键,%@指定值,更安全规范 let predicate = NSPredicate(format: "%K == %@", attribute, value) // 初始化查询描述符时传入谓词 let descriptor = FetchDescriptor<T>(predicate: predicate) // 执行查询并返回结果 let objects = try modelContainer.mainContext.fetch(descriptor) return objects }
简单说下逻辑:
- 先创建符合需求的
NSPredicate,这里的%K会被替换成传入的属性名,%@替换成对应的值 - 把这个谓词传给
FetchDescriptor的初始化方法,相当于告诉SwiftData我们要查询符合这个条件的实体 - 最后用上下文的
fetch方法执行查询,和Core Data的调用方式几乎一致
如果之后你需要添加排序规则,也可以在初始化FetchDescriptor的时候加上sortDescriptors参数,比如:
let sortDescriptor = SortDescriptor(\T.timestamp, order: .reverse) let descriptor = FetchDescriptor<T>(predicate: predicate, sortDescriptors: [sortDescriptor])
是不是很简单?和你之前用Core Data的思路完全打通,只是换了个容器来装查询规则而已~
内容来源于stack exchange
相关产品推荐
相关产品推荐

