FetchDescriptor<PiggyBank>() 是 SwiftData 的查询描述符(Fetch Descriptor),用于描述一次数据获取(fetch)的方式。
基本用法
let request = FetchDescriptor<PiggyBank>()
这表示查询 PiggyBank 模型,不排序,不过滤,返回所有记录。
然后用 context 获取数据:
let result = try context.fetch(request)
常用功能
FetchDescriptor实现排序(配合SortDescriptor)、过滤和限制数量。
1、排序
let request = FetchDescriptor<PiggyBank>(
sortBy: [SortDescriptor(\.creationDate)]
)
2、过滤
let request = FetchDescriptor<PiggyBank>(
predicate: #Predicate { $0.isPrimary == true }
)
3、限制数量
let request = FetchDescriptor<PiggyBank>(
fetchLimit: 20
)
也可以组合使用:
let request = FetchDescriptor<PiggyBank>(
predicate: #Predicate { $0.targetAmount > 100 },
sortBy: [SortDescriptor(\.creationDate, order: .reverse)],
fetchLimit: 10
)
@Query不使用FetchDescriptor
SwiftUI中使用@Query通常不使用FetchDescriptor,这是因为@Query默认生成等价的FetchDescriptor。
例如:
@Query(sort: \PiggyBank.creationDate)
var piggyBanks: [PiggyBank]
等价于:
let request = FetchDescriptor<PiggyBank>(
sortBy: [SortDescriptor(\.creationDate)]
)
let piggyBanks = try context.fetch(request)
使用场景
SwiftUI使用 @Query 获取、筛选数据,因此通常只在ViewModel或底层数据层中,使用ModelContext手动fetch。
例如,在ViewModel文件中:
let fetchRequest = FetchDescriptor<PiggyBank>()
let existingPiggyBanks = try context.fetch(fetchRequest)
因为不在View视图文件中,无法使用 @Query,因此只能手动从上下文中fetch获取数据。
总结
FetchDescriptor是SwiftData的查询描述符,获取最新的数据查询。
等价于UI层的 @Query。
此外,还有一种写法更简洁:
let result = try context.fetch(FetchDescriptor<PiggyBank>())
这表示从 SwiftData 中不过滤条件,直接获取全部数据。
如果视图需要传递一个 SwiftData 对象,就需要通过 @Query 或者 FetchDescriptor 从上下文中获取对象,然后传递给视图。
如果不从上下文中获取对象,而是传入一个普通的对象,就会报错。
相关文章
1、SwiftData框架属性包装器@Query:SwiftData框架属性包装器@Query:https://fangjunyu.com/2024/11/04/swiftdata%e6%a1%86%e6%9e%b6%e5%b1%9e%e6%80%a7%e5%8c%85%e8%a3%85%e5%99%a8query/
2、SwiftData中ModelContainer上下文绑定导致预览报错问题:https://fangjunyu.com/2024/12/27/swiftdata%e4%b8%admodelcontainer%e4%b8%8a%e4%b8%8b%e6%96%87%e7%bb%91%e5%ae%9a%e5%af%bc%e8%87%b4%e9%a2%84%e8%a7%88%e6%8a%a5%e9%94%99%e9%97%ae%e9%a2%98/
3、Swift排序规则SortDescriptor:https://fangjunyu.com/2025/11/22/swift%e6%8e%92%e5%ba%8f%e8%a7%84%e5%88%99sortdescriptor/
