Ghost108 Ghost108 - 1 month ago 10
Swift Question

NSPredicate - search with date attribute

I have a NSTableview which gets the date of core data.
In my entity is an attribute of type


Now i would like to realize a search function.
For this I have this code:

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

But I don't know how the predicate has to be, if I filter my result with the attribute

For example:

  • search field value = 01.12 => show all data where core data date 01.12.xxxx

  • search field value = 12.2017 => show all data where core data date xx.12.2017

  • search field value = 2017 => show all data where core data date xx.xx.2017

and so on

I hope you understand my problem and you can help me :)

Answer Source

As it was already mentioned it's a tricky case. But it can be done I believe. As Alex advised, you can use DateComponents to compare and find required dates. But to do this, you should define additional variable in your Data Model Class for your CoreData table. Example:

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

Unfortunately you cannot use it as a predicate. But this defined variable will allow you to use it after you fetched data from table. You can easily implement filtering using cycle. So I suggest you to go this way:

  1. Define variable in your data model class. This will allow you to filter out fetched results after you fetched data.

  2. Implement additional logic for predicate. This will allow you to minimize number of records to be pulled from database table.

For example: Input string is 06.2017 (MM.YYYY). You can convert this into two variables with type Date (NSDate) using DateFormatter and then use both variables as predicate:

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

So this will only help you to decrease number of records that will be pulled from table. But in case if input string will be like 12.02.XXXX this will not help you.