0

I have a Core Data model with an NSDate property. I want to filter the database by typing in any text such as a month and/or a year e.g. "May", "2001", "May 2001" etc. The 1st example would bring back any objects where the month of the data is May, the 2nd would bring back objects for the year 2001, the 3rd would bring back objects for May 2001.

I assume the solution will involve an NSPredicate, but I'm not sure how to put it all together.

Can I format the NSDate property somehow and simply do a [contains] searchtext?

Any suggestions would be greatly appreciated.

Alan
  • 93
  • 7

2 Answers2

0
NSDate *today = [NSDate date];
NSDate *yesterday = [today dateByAddingTimeInterval: -86400.0];
NSDate *thisWeek  = [today dateByAddingTimeInterval: -604800.0];
NSDate *lastWeek  = [today dateByAddingTimeInterval: -1209600.0];

NSArray *dates = @[today, yesterday, thisWeek, lastWeek];

NSArray *filteredArray = [dates filteredArrayUsingPredicate:
 [NSPredicate predicateWithBlock:^BOOL(NSDate *item, NSDictionary *bindings) {

    // Logic for searching comes here
    // For instance date with day 27 
    NSDateComponents *components = [[NSCalendar currentCalendar] components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) fromDate:item];
    NSInteger day = [components day];
    return (day == 27);

}]];

NSLog(@"%@",filteredArray);
iCoder
  • 1,645
  • 1
  • 15
  • 23
  • Thanks for your reply. It pointed me in the right direction - much appreciated! – Alan Jun 27 '13 at 22:30
  • ok, so this didnt work because it appears NSPredicate with block is not supported in Core Data – Alan Jun 28 '13 at 05:28
  • NSPredicate is a class in Foundation.framework. What do u mean by not supported in core data. Can you elaborate? – iCoder Jun 28 '13 at 05:32
  • Maybe I am wrong, but using it in a fetch request throws an exception. I am having the same issues as discussed in http://stackoverflow.com/questions/3543208/nsfetchrequest-and-predicatewithblock as I am using SQlLite – Alan Jun 29 '13 at 12:35
0

You could always get the date as string using NSDateFormatter (or simple description method) and do a check for particular string. But for this you will have to get all objects from your store which will be very inefficient. Instead you could create another relationship (or custom attribute) to a Date entity which will have day, month and year information. (You can have this along with the date attribute or without it). Then it will be easy to write predicates whatever may be the type of search you are trying to perform - month, date or day.

And for setting and getting the attribute you could use custom methods in the NSManagedObject subclass for the entity.

For eg: if your entity is Event which looks like

Event

  • eName
  • eDate   (Another Entity EventDate- one to one relationship)

and EventDate looks like

EventDate

  • day
  • month
  • year

then for setting using date

-(void)setEDateUsingDate:(NSDate *)date{
//gather current calendar
    NSCalendar *calendar = [NSCalendar currentCalendar];

    //gather date components from date
    NSDateComponents *dateComponents = [calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) fromDate:date];

    //set date components
    self.eDate.day=[dateComponents day];
    self.eDate.month=[dateComponents month];
    self.eDate.year=[dateComponents year];
}

and getting the date would be

-(NSDate *)dateFromEDate{
    NSCalendar *calendar = [NSCalendar currentCalendar];
    NSDateComponents *components = [[NSDateComponents alloc] init];
   [components setDay:self.eDate.day];
   [components setMonth:self.eDate.month];
   [components setMonth:self.eDate.year];
   NSDate *date = [calendar dateFromComponents:components];
   return date;
}
Rakesh
  • 3,370
  • 2
  • 23
  • 41
  • Thanks or your suggestion. I would prefer not to have to create another attribute at these stage but may have to go that route if I don't find a better method. – Alan Jul 01 '13 at 12:57