Search code examples
ioscore-datanspredicatensfetchedresultscontroller

NSFetchedResultsController with complicate predicate


I'm developing the app with UICollectionView.
It's collection of events arranged by date. I'm using NSFetchedResultsController to fetch data from DB. But I need to fetch current and future events + 2 past events. For NSFetchRequest I'm using NSCompoundPredicate

NSPredicate *nextPredicate = [NSPredicate predicateWithFormat: @"startAt >= %@", [NSDate date]];
NSPredicate *previousPredicate = [NSPredicate predicateWithFormat:@"startAt < %@", [NSDate date]];
NSCompoundPredicate *resultPredicate = [NSCompoundPredicate andPredicateWithSubpredicates: @[nextPredicate, previuosPredicate]];
fetchRequest.predicate = resultPredicate;

And I have no idea how to limit previousPredicate to receive only 2 items.


Solution

  • If you know the date of current event than create a method that return date of the last event to fetch and then set the predicate on the main NSFetchRequest to that date.

     -(NSDate *)dateOfPastEvent{
        NSFetchRequest *request = [[NSFetchRequest alloc]init];
        NSEntityDescription *entity = [NSEntityDescription entityForName:@"EntityName" inManagedObjectContext:_mainContext];
        [request setEntity:entity];
    
        NSSortDescriptor *sortDesc = [NSSortDescriptor sortDescriptorWithKey:@"startAt" ascending:NO];
        [request setSortDescriptors:@[sortDesc]];
    
        NSError *error = nil;
        NSArray *array = [_mainContext executeFetchRequest:request error:&error];
    
    
        __block NSDate *pastEventDate;
    
        [array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop){
    
            if ([obj valueForKey:@"startAt"] == currentEventDate) {
                if (array.count >= idx+2) {
                    pastEventDate = [[array objectAtIndex:idx+2] valueForKey:@"startAt"];
                    *stop = YES;
                }
    
            }
        }];
    
    
        return pastEventDate;
    
    }
    

    Now set the predicate for the above returned date

      NSFetchRequest *requestForController = [[NSFetchRequest alloc]init];
      NSEntityDescription *entity = [NSEntityDescription entityForName:@"EntityName" inManagedObjectContext:_mainContext];
        [requestForController setEntity:entity];
    
      NSPredicate *predicate = [NSPredicate predicateWithFormat: @"startAt >= %@", [self dateOfPastEvent]];