排序/过滤NSFetchRequest如何编写将使用当前日期的排序描述符?

时间:2014-06-09 09:07:12

标签: ios sorting filter nsfetchrequest nsfetchedresultscontroller

我存储在Core Data 2个日期属性中,一个是过期日期,第二个是“琥珀色”日期(过期日期前X周的日期)。我想按以下方式对结果进行排序:

  • 琥珀色日期之前的项目 - (绿色)现在<琥珀
  • 在琥珀色日期之后但在到期日之前的项目 - (琥珀色)琥珀色< = now<到期
  • 过期日期或之后的项目 - (红色)过期< = now

你能帮帮我吗?

更新 经过更多的研究,我发现我可以获取未排序的结果,将其放入数组并对数组进行排序,并且表将使用此数组作为数据源 - 太多而无法更改以使其在我的应用程序中运行。 此外,还可以使用额外的参数,该参数将根据上面的列表保存评估值。然后获取将需要两个步骤:

  1. 获取数据并对每个项目运行评估
  2. 通过此获取已排序的数据 评估财产
  3. 后一种解决方案是我最好的选择,那么任何人都可以帮我解决这个问题吗?

    修改

    state属性定义为int16_t

    @property (nonatomic, assign) int16_t state;
    

    在带有表的视图的viewDidLoad中,我在获取排序结果之前调用fallowing:

     NSFetchRequest *fetchRequest = 
    [NSFetchRequest fetchRequestWithEntityName:@"MyTable"];
        NSSortDescriptor *sortTitle = 
        [NSSortDescriptor sortDescriptorWithKey:@"name"
                                      ascending:YES];
        [fetchRequest setSortDescriptors:@[sortByTitle]];
    
        NSFetchedResultsController *ctrl = [[NSFetchedResultsController alloc]
                    initWithFetchRequest:fetchRequest
                    managedObjectContext:[NSManagedObjectContext defaultContext]
                      sectionNameKeyPath:nil
                               cacheName:nil];
    
        NSError* fetchError = nil;
        if([ctrl performFetch:&fetchError] == NO) {
    
            NSLog(@"Error: perform fetch failed, %@",[fetchError description]);
    
        } else {
            //do we have results here?
            id <NSFetchedResultsSectionInfo> sectionInfo = 
                                          [ctrl.sections objectAtIndex:0];
            NSArray * items = [sectionInfo objects];
            for (int i=0; i<items.count; i++) {
                CourseCD* item = items[i];
                NSLog(@"%d - %@",i,item);
                [item evaluateState];//category adds this method
            }
        }
    

    这是类别

    的方法
    -(State) evaluateState {
        CourseComplianceState pState = StateUnknown;
        if (self.expire == nil) {
            [self setState:pState];
            return pState;
        }
    
        NSDate* now = [[NSDate alloc] init];
        pState = StateNotExpired;
    
        if ([NSDate isDate:now inRangeFirstDate:self.thresholdDate 
                  lastDate:self.expireDate]) {
            //amber
            pState = StateWithinThreshold;
        } else if ([NSDate isDate:now inRangeFirstDate:self.expireDate 
                         lastDate:[NSDate distantFuture]]){
            //expired
            pState = StateExpired;
        }
    
        //
        [self setState:pState];
    
        NSLog(@" - evaluateState -");
    
        return pState;
    }
    

    这是State struct

    enum {
        StateUnknown,
        StateNotExpired,
        StateWithinThreshold,
        StateExpired
    
    };
    typedef int16_t State;
    

    然后在这次通话之后我使用以下排序的目的地呼叫,并且我正在使用与表一起工作的控制器。

    //later I use following sort descriptors
    NSSortDescriptor *sortState = [NSSortDescriptor 
                                      sortDescriptorWithKey:@"state"
                                                  ascending:YES];
    NSSortDescriptor *sortExpire = [NSSortDescriptor 
                                      sortDescriptorWithKey:@"expire"
                                                  ascending:YES];
    

    修改

    NSSortDescriptor *sortByTitle = [NSSortDescriptor 
                                       sortDescriptorWithKey:@"name" 
                                                   ascending:YES];
    NSFetchRequest *fetchRequest = [NSFetchRequest 
                                     fetchRequestWithEntityName:@"Course"];
    [fetchRequest setSortDescriptors:@[sortState,sortExpire,sortByTitle]];
    
    
    self.resultsController = [[NSFetchedResultsController alloc] 
                               initWithFetchRequest:fetchRequest
                       managedObjectContext:[NSManagedObjectContext defaultContext]
                                 sectionNameKeyPath:nil
                                          cacheName:nil];
    
    self.resultsController.delegate = self;
    
    NSError* fetchError = nil;
    if([self.resultsController performFetch:&fetchError] == NO) {
    
        NSLog(@"Error: perform fetch failed, %@",[fetchError description]);
    
    }
    

    但它只在到期日期之前排序,并且第一次评估运行会忽略或不保存状态。

    编辑2014/06/10

    这是NSManagedObject类中的setter

    //.h
    @property (nonatomic, assign) int16_t state;
    
    //.m
    @synthesize state=_state;
    -(void) setState:(int16_t)state {
        _state = state;
    
        NSError* error = nil;
        [[NSManagedObjectContext defaultContext] save:&error];
        if(error != nil){
            NSLog(@"Error in setState, details:%@",[error description]);
        }
    }
    

    最终编辑 - 已解决

    决议是: 移除@synthesise state = _state;-(void) setState:(int16_t)state {}并离开@dynamic state。然后在evaluateState而不是[self setState:pState];我使用了self.state=pState;,现在根据需要对其进行排序。现在的问题是为什么合成属性它不起作用?

1 个答案:

答案 0 :(得分:0)

决议是:删除@synthesise state = _state;-(void) setState:(int16_t)state {}并离开@dynamic状态。然后在evaluateState而不是[self setState:pState];我使用了self.state=pState;,现在根据需要对其进行排序。