【问题标题】: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)
}
很遗憾,您不能将其用作谓词。但是这个定义的变量将允许您在从表中获取数据后使用它。您可以使用循环轻松实现过滤。所以我建议你走这条路:
在数据模型类中定义变量。这将允许您在获取数据后过滤掉获取的结果。
为谓词实现附加逻辑。这将允许您最大限度地减少从数据库表中提取的记录数。
例如:
输入字符串是 06.2017 (MM.YYYY)。您可以使用 DateFormatter 将其转换为 Date (NSDate) 类型的两个变量,然后将这两个变量用作谓词:
request.predicate = NSPredicate(format: "someDate > %@ and somedate < %@", inputDateStart as NSDate, inputDateEnd)
因此,这只会帮助您减少将从表中提取的记录数。但是如果输入字符串像 12.02.XXXX 这不会帮助你。