首页 > 解决方案 > swift coredata 查询不适用于今天的日期

问题描述

我有一个名为 Places 的类,由 CoreData 管理。此对象有一个 Date 对象作为时间戳。

我有这个查询来探测今天的地方。问题是我今天只登录了 2 个地方,但是它给我带来了 21 条记录,这是我没想到的

func updatePlaceMarksForADateFromDatabase(date: Date) {
    var calendar = Calendar.current
    calendar.timeZone = TimeZone(identifier: "UTC")!
    let dateFrom = calendar.startOfDay(for: date)
    let dateTo = calendar.date(byAdding: .day, value: 1, to: dateFrom)
    
    // Set predicate as date being compliant with date
    let fromPredicate = NSPredicate(format: "%@ >= %@", date as NSDate, dateFrom as NSDate)
    let toPredicate = NSPredicate(format: "%@ < %@", date as NSDate, dateTo! as NSDate)
    let datePredicate = NSCompoundPredicate(andPredicateWithSubpredicates: [fromPredicate, toPredicate])

    // CoreData API's to list only today places
    let fetchRequest: NSFetchRequest<Places> = Places.fetchRequest()
    fetchRequest.predicate = datePredicate
    if let context = (UIApplication.shared.delegate as? AppDelegate)?
        .persistentContainer.viewContext {
      let sort = NSSortDescriptor(key: #keyPath(Places.timestamp), ascending: false)
      fetchRequest.sortDescriptors = [sort]
      if let placesCoreData = try?
          context.fetch(fetchRequest) {
        // Store it to the cache
        print(placesCoreData.count)
      }
    }
  }

标签: swiftcore-data

解决方案


你的谓词是错误的。

let fromPredicate = NSPredicate(format: "%@ >= %@", date as NSDate, dateFrom as NSDate)
let toPredicate = NSPredicate(format: "%@ < %@", date as NSDate, dateTo! as NSDate)
let datePredicate = NSCompoundPredicate(andPredicateWithSubpredicates: [fromPredicate, toPredicate])

您没有针对Places. 目前,它等价于NSPredicate(value: true),因为date大于或等于dateFrom且小于dateTo。它应该始终为真(根据值的创建方式)。这就是为什么你在获取时会得到所有的地方。

它应该是:

let fromPredicate = NSPredicate(format: "%K >= %@", argumentArray: [#keyPath(Places.dateVariableName), dateFrom]
let toPredicate = NSPredicate(format: "%K < %@", argumentArray: [#keyPath(Places.dateVariableName), dateTo]

推荐阅读