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];