SwiftUI:带NSPredicate的@FetchRequest日期查询问题排查
问题分析与修正
你的代码存在两个关键问题,导致FetchRequest无法返回正确结果:
- 运算符语法错误:
=<是无效的比较运算符,Core Data的NSPredicate中小于等于的正确写法是<=。 - 日期类型不匹配:直接在Predicate字符串中写
2023-01-29会被解析为数值(2023-1-29=1993),而你的transactionDate是Date类型,数值和日期类型无法正确比较,自然不会匹配任何数据。
修正后的代码
你需要将日期字符串转换为Date实例,再通过占位符传入Predicate,同时修正运算符:
import SwiftUI import CoreData struct YourView: View { // 初始化日期格式化器,用于将字符串转为Date实例 private let dateFormatter: ISO8601DateFormatter = { let formatter = ISO8601DateFormatter() formatter.formatOptions = .withFullDate return formatter }() // 解析起始和结束日期(实际项目建议添加错误处理,避免强制解包) private var startDate: Date { dateFormatter.date(from: "2023-01-29")! } private var endDate: Date { dateFormatter.date(from: "2023-08-29")! } // 修正后的FetchRequest @FetchRequest( sortDescriptors: [], predicate: NSPredicate( format: "(name CONTAINS[cd] %@) AND (transactionDate >= %@) AND (transactionDate <= %@)", "bill", startDate, endDate ) ) var lists: FetchedResults<Expense> var body: some View { List(lists) { expense in Text(expense.name ?? "Unnamed") } } }
额外说明
- 实际开发中不要强制解包
date(from:)的结果,建议添加错误处理逻辑(比如设置默认日期或提示用户)。 CONTAINS[cd]中的[cd]表示忽略大小写和重音,这个部分是正确的,无需修改。- 如果需要动态调整日期范围,可以将
startDate和endDate改为绑定变量,配合@State或@Binding实现。
内容的提问来源于stack exchange,提问作者mzkn
相关产品推荐
相关产品推荐

