こんにちは。きんくまです。
またまた備忘録です。
DBからNSManagedObjectでなく、EntityのAttributeの最大値や平均をもとめたいときがあります。
最初はManagedObject全部引っ張ってきて手動で計算するのかな?と思ったのですが、ちゃんとやり方がありました。
Appleのドキュメントに書いてありましたです。
Core Data Programming Guide – Fetching Specific Values
今回のコードはここに書いてあるそのまんまです。すみません、、。
やり方
やり方は通常とちょっとだけ違っていて
1. NSFetchRequestにsetResultType:NSDictionaryResultTypeとすること
2. NSExpressionDescriptionをセットすること
となってます。FetchRequestの結果は通常と同じArrayなんですが、その中身がDictionaryになってるところがポイントです。
NSExpressionDescriptionの作り方
NSExpressionDescriptionを作るのがまた少し手間ですが
1. NSExpressionを作成
評価したいAttributeをセットして、さらにそいつを引数に使い、expressionForFunction:argumentsを作る感じです。
expressionForFunction:argumentsの最初の引数は求めたいタイプ(最大値、最小値、平均など)を入れます。
そのリストはここにあります。
>> expressionForFunction:arguments:
例えば最大値なら@”max:”となります。
NSExpression *keyPathExpression = [NSExpression expressionForKeyPath:@"salary"]; NSExpression *maxSalaryExpression = [NSExpression expressionForFunction:@"max:" arguments:[NSArray arrayWithObject:keyPathExpression]];
2. NSExpressionDescriptionを作る
NSExpressionDescription *expressionDescription = [[NSExpressionDescription alloc] init]; [expressionDescription setName:@"maxSalary"]; [expressionDescription setExpression:maxSalaryExpression]; [expressionDescription setExpressionResultType:NSDecimalAttributeType];
nameはfetchで返ってくるdictionaryのキーになります。
expressionは1でつくったNSExpressionです。
expressionResultTypeはNSAttributeType一覧にあります。返ってくるdictionaryの値のタイプです。整数、小数、日付とかです。
3.NSFetchRequestにセット
最後にfetchRequestにセットして準備完了です。
[request setPropertiesToFetch:[NSArray arrayWithObject:expressionDescription]];
とおして書いてみる
公式のサンプルのまねして書いてみるとこんな感じ。
- (NSInteger)maxDisplayOrderValue { NSFetchRequest *req = [[NSFetchRequest alloc] init]; NSEntityDescription *entity = [NSEntityDescription entityForName:@"Event" inManagedObjectContext:self.managedObjectContext]; [req setEntity:entity]; [req setResultType:NSDictionaryResultType]; NSExpression *keyPathExpression = [NSExpression expressionForKeyPath:@"displayOrder"]; NSExpression *maxExpression = [NSExpression expressionForFunction:@"max:" arguments:@[keyPathExpression]]; NSExpressionDescription *expressionDescription = [[NSExpressionDescription alloc] init]; [expressionDescription setName:@"maxDisplayOrder"]; [expressionDescription setExpression:maxExpression]; [expressionDescription setExpressionResultType:NSInteger32AttributeType]; [req setPropertiesToFetch:@[expressionDescription]]; NSError *error = nil; NSArray *obj = [self.managedObjectContext executeFetchRequest:req error:&error]; NSInteger maxValue = NSNotFound; if(obj == nil){ NSLog(@"error"); }else if([obj count] > 0){ maxValue = [obj[0][@"maxDisplayOrder"] integerValue]; } return maxValue; }
■ 自作iPhoneアプリ 好評発売中!
・フォルメモ - シンプルなフォルダつきメモ帳
・ジッピー電卓 - 消費税や割引もサクサク計算!
■ LINEスタンプ作りました!
毎日使える。とぼけたウサギ