0

我无法从按日期排序的核心数据中提取结果。从核心数据提取按格式化日期排序

我有一个包含足球比赛的数据库表。每场比赛都有主队,客队和开球时间。 kickoffTime是一个NSDate,用于存储比赛开始的日期和时间。

我想在一个TableView中显示一个查询的结果,这个查询被开始日期分为几个部分。以日期作为部分标题。

这比它首次出现时要复杂一点。由于时区不同,世界某个地区的某一天开始的比赛实际上是在另一个世界的不同日期开始的。所以我不能简单地忽略时间并将开始日期存储在另一列中。

我想要做的是创建一个自定义访问器,该访问器返回格式化日期,在用户所处的任何时区,然后使用它对结果进行排序和分区。下面是Match.h我的代码:

@dynamic kickoffTime; 
@dynamic formattedKickoffTime; 
@dynamic dateFormatter; 

- (NSString *)formattedKickoffTime 
{ 
    [self willAccessValueForKey:@"kickoffTime"]; 

    // Set the date formatter to the format we want to display the date 
    [dateFormatter setDateFormat:@"ccc, d MMM"]; 

    // Format the date 
    NSString *myFormattedKickoffTime = [dateFormatter stringFromDate:[self kickoffTime]]; 

    [self didAccessValueForKey:@"kickoffTime"]; 

    // return the formatted date 
    return myFormattedKickoffTime; 
} 

- (NSDateFormatter *)dateFormatter 
{ 
    if (dateFormatter == nil) 
    { 
     dateFormatter = [[NSDateFormatter alloc] init]; 
    } 
    return dateFormatter; 
} 

@end 

然而,当我尝试获取与像这样的数据进行排序:

NSSortDescriptor *kickoffDescriptor = [[NSSortDescriptor alloc] initWithKey:@"formattedKickoffTime" ascending:YES]; 
... 
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:appDelegate.managedObjectContext sectionNameKeyPath:@"formattedKickoffTime" cacheName:nil]; 

我收到以下错误信息:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'keypath formattedKickoffTime not found in entity <NSSQLEntity Match id=1>' 

会有人提供一些建议吗?

回答

0

所以我找到了一种方法来做到这一点。首先,我用GMT保存模型中的所有日期和计算。我添加一个自定义访问器(kickoffDate)到我的Match实体,该实体获取kickoffTime,将其设置为00:00:00并将其返回。我不得不做的一件事情,那并不明显,就是将自定义访问器返回的日期的时区设置为GMT,否则这将被设置为用户的系统时区。

由于模型返回的所有日期都是格林威治标准时间,所有东西似乎都能正常工作,无论我在iPhone的“设置”中设置了多少时间区域。我猜核心数据足够聪明,可以在将比赛放入部分之前进行时间区域调整。

虽然我确实有一个问题,是[NSTimeZone timeZoneForSecondsFromGMT:0]获得0时区的最佳方法,我的意思是一个不受夏令时影响的时区?

哦,我必须拨打[self willAccessValueForKey:@"kickoffTime"];[self didAccessValueForKey:@"kickoffTime"];吗?我真的不明白他们在做什么!

下面是Match.h代码:

... 
@dynamic homeTeam; 
@dynamic awayTeam; 
@dynamic kickoffTime; 

- (NSDate *)kickoffDate 
{ 
    [self willAccessValueForKey:@"kickoffTime"]; 
    NSCalendar *cal = [NSCalendar currentCalendar]; 
    NSDateComponents *components = [cal components:(NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit) fromDate:[self primitiveValueForKey:@"kickoffTime"]]; 
    [components setHour:0]; 
    [components setMinute:0]; 
    [components setSecond:0]; 
    [components setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]]; 

    [self didAccessValueForKey:@"kickoffTime"]; 
    return [cal dateFromComponents:components]; 
} 

,然后我的取出码包括上kickoffTime以下排序和sectionNameKeyPath设置为kickoffDate:

NSSortDescriptor *kickoffDescriptor = [[NSSortDescriptor alloc] initWithKey:@"kickoffTime" ascending:YES]; 
... 
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:appDelegate.managedObjectContext sectionNameKeyPath:@"kickoffDate" cacheName:nil];