【问题标题】:NSPredicate - search with date attributeNSPredicate - 使用日期属性搜索
【发布时间】:2018-02-01 06:19:27
【问题描述】:

我有一个获取核心数据日期的 NSTableview。 在我的实体中是Date 类型的属性。

现在我想实现一个搜索功能。 为此,我有以下代码:

@IBAction func search(_ sender: NSSearchField) {
   let predicate : NSPredicate?
      if sender.stringValue.isEmpty {
         predicate = nil
      } else {
         predicate = // ?
      }
   requestData(predicate: predicate)
}

但是如果我使用属性Date 过滤我的结果,我不知道谓词必须是什么

例如:

  • 搜索字段值 = 01.12 => 显示核心数据日期为 01.12.xxxx 的所有数据
  • 搜索字段值 = 12.2017 => 显示核心数据日期为 xx.12.2017 的所有数据
  • 搜索字段值 = 2017 => 显示核心数据日期为 xx.xx.2017 的所有数据

等等

我希望你能理解我的问题并帮助我:)

【问题讨论】:

    标签: swift macos core-data


    【解决方案1】:

    如果您对日期使用 Date 类型,则可以将日期分隔到 DateComponents 中:

    let date = Date()
    let calendar = Calendar(identifier: .gregorian)
    let components = calendar.dateComponents([.year, .month, .day], from: date)
    
    print(components.day, components.month, components.year)
    

    然后您可以简单地按这些组件进行比较和过滤。

    【讨论】:

      【解决方案2】:

      我认为您在尝试使用 NSSearchField 搜索日期时会遇到一些问题,因为将用户输入的内容转换为可行的 Date 对象将涉及大量逻辑,这是一个简单的示例将是来自美国的用户输入 2/8/2017 表示 2017 年 2 月 2 日,而欧洲公民则表示 2017 年 8 月 2 日。

      还有一个问题是用户将“上周四”之类的内容绑定到搜索字段中并将其翻译成Date 对象。

      我对此的建议是实现某种 UI 控件,例如日期选择器,它可以轻松地将用户输入转换为可用的 Date 对象。

      除此之外,您可以通过执行以下操作来构造使用日期对象的谓词:

      let now: Date = Date()        
      let predicate: NSPredicate = NSPredicate(format: "date < %@", now as NSDate)
      

      希望对你有帮助。

      【讨论】:

        【解决方案3】:

        正如已经提到的,这是一个棘手的案例。但我相信这是可以做到的。 正如 Alex 建议的那样,您可以使用 DateComponents 来比较和查找所需的日期。但要做到这一点,你应该在你的数据模型类中为你的 CoreData 表定义额外的变量。示例:

        var calendar = Calendar(identifier: .gregorian)
        var openDateComponents: DateComponents {
            return calendar.dateComponents([.year, .month, .day], from: openTime! as Date)
        }
        

        很遗憾,您不能将其用作谓词。但是这个定义的变量将允许您在从表中获取数据后使用它。您可以使用循环轻松实现过滤。所以我建议你走这条路:

        1. 在数据模型类中定义变量。这将允许您在获取数据后过滤掉获取的结果。

        2. 为谓词实现附加逻辑。这将允许您最大限度地减少从数据库表中提取的记录数。

        例如: 输入字符串是 06.2017 (MM.YYYY)。您可以使用 DateFormatter 将其转换为 Date (NSDate) 类型的两个变量,然后将这两个变量用作谓词:

        request.predicate = NSPredicate(format: "someDate > %@ and somedate < %@", inputDateStart as NSDate, inputDateEnd)
        

        因此,这只会帮助您减少将从表中提取的记录数。但是如果输入字符串像 12.02.XXXX 这不会帮助你。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-10-09
          • 2010-12-30
          • 2020-08-05
          • 2022-08-18
          • 1970-01-01
          相关资源
          最近更新 更多