You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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")
        }
    }
}

额外说明

  1. 实际开发中不要强制解包date(from:)的结果,建议添加错误处理逻辑(比如设置默认日期或提示用户)。
  2. CONTAINS[cd]中的[cd]表示忽略大小写和重音,这个部分是正确的,无需修改。
  3. 如果需要动态调整日期范围,可以将startDate和endDate改为绑定变量,配合@State或@Binding实现。

内容的提问来源于stack exchange,提问作者mzkn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 18:13:38