私はこの問題を1週間にわたって調査していて、解決策がないので、質問をより一般化することを考えました。ユーザーが問題を調べて解決策を提供するのに役立つかもしれません。
シナリオ:
私はiOSアプリケーションを追跡する経費を持っており、「DashBoardViewController」(テーブルビューコントローラー-FRC付き)と呼ばれるビューコントローラーを持っています。これは基本的に、特定の週、月、または年の経費/収入を分類し、セクションヘッダーとして表示しますたとえば、タイトル:(2012年10月1日から10月7日)。特定の週、月、または年に応じて、費用/収入のROWSおよび関連するものが表示されます。
私の質問:
私が達成したいのは:
「Money」エンティティの「Category」属性に基づいて個別の結果を表示し、属性に基づいて「Sum」を計算します。
しかし、「ダッシュボードビューコントローラー」と呼ばれる私のビューコントローラーは、費用または収入になる可能性のある「タイプ」としてのセクション名キーパスを持つNSFetchedResultsControllerで満たされています。個別の結果を取得するために、フェッチリクエストで結果タイプをNSDictionaryResultsTypeとして使用します。これにより、一意の結果が得られますが、FRCは失敗し、それでは機能しません。では、どのようにしてセクション名を取得しますか?以下のコードを投稿しました。
編集-マーティンの提案に基づく
- (void)userDidSelectStartDate:(NSDate *)startDate andEndDate:(NSDate *)endDate
{
AppDelegate * applicationDelegate = (AppDelegate *) [[UIApplication sharedApplication] delegate];
NSManagedObjectContext * context = [applicationDelegate managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
// Edit the entity name as appropriate.
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Money" inManagedObjectContext:context];
[fetchRequest setEntity:entity];
// Set the batch size to a suitable number.
[fetchRequest setFetchBatchSize:20];
NSPredicate *predicateDate = [NSPredicate predicateWithFormat:@"(date >= %@) AND (date <= %@)", startDate, endDate];
[fetchRequest setPredicate:predicateDate];
// Edit the sort key as appropriate.
typeSortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"type" ascending:YES];
dateSortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"date" ascending:YES];
if(self.choiceSegmentedControl.selectedIndex == 0)
{
choiceSortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"cat" ascending:NO];
}
if(self.choiceSegmentedControl.selectedIndex == 1)
{
choiceSortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"vendor" ascending:NO];
}
if(self.choiceSegmentedControl.selectedIndex == 2)
{
choiceSortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"paidBy" ascending:NO];
}
NSArray * descriptors = [NSArray arrayWithObjects:typeSortDescriptor, dateSortDescriptor,choiceSortDescriptor, nil];
[fetchRequest setSortDescriptors:descriptors];
[fetchRequest setIncludesSubentities:YES];
NSError * anyError = nil;
NSArray *propertiesToFetch = [[NSArray alloc] initWithObjects:
[entity.propertiesByName objectForKey:@"cat"],
nil];
[fetchRequest setReturnsDistinctResults:YES];
[fetchRequest setResultType:NSDictionaryResultType];
[fetchRequest setPropertiesToFetch:propertiesToFetch];
NSArray * objects = [context executeFetchRequest:fetchRequest error:&anyError];
for (NSDictionary *d in objects)
{
NSLog(@"NSDictionary = %@", d);
}
NSSet *uniqueSet = [NSSet setWithArray:[objects valueForKey:@"cat"]];
uniqueArray = [NSMutableArray arrayWithArray:[uniqueSet allObjects]];
self.categoryArray = uniqueArray;
if(_fetchedResultsController)
{
[_fetchedResultsController release]; _fetchedResultsController = nil;
}
_fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:context sectionNameKeyPath:@"type" cacheName:nil];
//self.fetchedResultsController.delegate = self; in order to stop "change tracking"
if(![_fetchedResultsController performFetch:&anyError])
{
NSLog(@"error fetching:%@", anyError);
}
[fetchRequest release];
//Finally you tell the tableView to reload it's data, it will then ask your NEW FRC for the new data
[self.dashBoardTblView reloadData];
self.startDate = startDate;
self.endDate = endDate;
}
このコードでは、SECTION NAME KEY PATHが機能せず、オブジェクトが名前のないセクションに配置されると文句を言っています。