Question

I am using a transient attribute to sort the core data objects into separate table view sections. It is called 'sectionIdentifier'. The getter for this attribute is inside a NSManagedObject subclass, called ToDoItem.m . The problem is that during app execution, the new added objects are always shown under the TODAY section. After a new launch of the app, all objects are shown under the expected row. I was told by an expert user, that when setting a new object, the sectionIdentifier must be invalidated, but I don't know how to invalidate it. Here is my NSManagedObject subclass code:

#import "ToDoItem.h"
#import "ToDoGroup.h"
#import "ToDoSubItem.h"


@implementation ToDoItem

@dynamic todoDescription;
@dynamic todoName;
@dynamic todoDueDate;
@dynamic sectionIdentifier;
@dynamic todogroup;
@dynamic todosubitems;



-(NSString *)sectionIdentifier{

    [self willAccessValueForKey:@"sectionIdentifier"];
    NSString *tmp = [self primitiveValueForKey:@"sectionIdentifier"];
    [self didAccessValueForKey:@"sectionIdentifier"];

    if (!tmp){

        NSDate *date = self.todoDueDate;
        NSDate *todayDate = [NSDate date];

        NSLog(@"date= %@",date);
        NSLog(@"todayDate = %@",todayDate);


        NSCalendar *calendar = [NSCalendar currentCalendar];
        NSInteger comps = (NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit);
        NSDateComponents *date1Components = [calendar components:comps fromDate:date];
        NSDateComponents *date2Components = [calendar components:comps fromDate:todayDate];
        date = [calendar dateFromComponents:date1Components];
        todayDate = [calendar dateFromComponents:date2Components];




        if([date
            compare:todayDate] == NSOrderedSame) {
            tmp = @"1";//TODAY
        }
        else if([date
                 compare:todayDate] == NSOrderedDescending){
            tmp = @"2";//OVERDUE
        }
        else if ([date
                  compare:todayDate] == NSOrderedAscending){
            tmp =@"0";//UPCOMING
        }
        NSLog(@"Tmp= %@",tmp);

        [self setPrimitiveValue:tmp forKey:@"sectionIdentifier"];

    }
    return tmp;

}


@end

Any help is welcome...

Was it helpful?

Solution

The problem is that the section identifier is calculated and cached from the todoDueDate, but not updated automatically when the todoDueDate changes.

The DateSectionTitles/APLEvent.m sample code from Apple shows how such an automatic update can be achieved.

In your case, you should add the following methods to the managed object subclass ToDoItem:

- (void)setTodoDueDate:(NSDate *)newDate
{
    // If the todoDueDate changes, the section identifier become invalid.
    [self willChangeValueForKey:@"todoDueDate"];
    [self setPrimitiveValue:newDate forKey:@"todoDueDate"];
    [self didChangeValueForKey:@"todoDueDate"];

    // Set the section identifier to nil, so that it will be recalculated
    // when the sectionIdentifier method is called the next time:
    [self setPrimitiveValue:nil forKey:@"sectionIdentifier"];
}

+ (NSSet *)keyPathsForValuesAffectingSectionIdentifier
{
    // If the value of todoDueDate changes, the section identifier may change as well.
    return [NSSet setWithObject:@"todoDueDate"];
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top