I have been experimenting trying to learn how to use NSExpressions to fetch aggregate info from Core Data. I have the fetch working properly but I'm having trouble trying to parse the resulting data for processing. I'm sure I must be missing something but I can't figure out what it is. I'm fetching the sum of an attribute on some entities and I have this part right. Then I want to do some math on the results but I am not getting the desired results.

Here is my sample code

[_mainContext save:nil];
NSMutableDictionary *accountBalances = [[NSMutableDictionary alloc] init];
NSFetchRequest* request = [[NSFetchRequest alloc] init];
request.entity = [NSEntityDescription entityForName:@"AccountTransaction"
                             inManagedObjectContext:_mainContext];

// build an expression to calculate the sum
NSExpressionDescription* totalOfTransactionsDescription = [[NSExpressionDescription alloc] init];

NSExpression *keyExpression = [NSExpression expressionForKeyPath:@"amount"];
NSExpression *theExpression = [NSExpression expressionForFunction:@"sum:"
                                                        arguments:@[keyExpression]];

[totalOfTransactionsDescription setName:@"totalOfTransactions"];
[totalOfTransactionsDescription setExpression:theExpression];
[totalOfTransactionsDescription setExpressionResultType:NSFloatAttributeType];

// we want the results in a dictionary
request.resultType = NSDictionaryResultType;
request.propertiesToFetch = @[totalOfTransactionsDescription];
NSArray* results;
NSDictionary* fetchResultsDictionary;
NSDecimalNumber *total;

// credits
request.predicate = [NSPredicate predicateWithFormat:@"isCredit == %@",[NSNumber numberWithBool:YES]];
results = [_mainContext executeFetchRequest:request error:nil];
fetchResultsDictionary = [results objectAtIndex:0];
total = [fetchResultsDictionary objectForKey:@"totalOfTransactions"];
[accountBalances setObject:total forKey:@"postedCredits"];

// debits
request.predicate = [NSPredicate predicateWithFormat:@"isCredit == %@",[NSNumber numberWithBool:NO]];
results = [_mainContext executeFetchRequest:request error:nil];
fetchResultsDictionary = [results objectAtIndex:0];
total = [fetchResultsDictionary objectForKey:@"totalOfTransactions"];
[accountBalances setObject:total forKey:@"postedDebits"];


// build an account balance
NSDecimalNumber *startingBalance = [NSDecimalNumber decimalNumberWithString:@"100.00"];
NSDecimalNumber *currentBalance = startingBalance;

// add deposits
currentBalance = [currentBalance decimalNumberByAdding:[accountBalances objectForKey:@"postedCredits"]];

// subtract debits
currentBalance = [currentBalance decimalNumberBySubtracting:[accountBalances objectForKey:@"postedDebits"]];

[accountBalances setObject:currentBalance forKey:@"currentBalance"];

NSLog(@"%@", accountBalances);

Here is my console log

2013-08-23 23:56:35.775 NSExpressionCoreDataTestApp[5162:907] {
    currentBalance = 100;
    postedCredits = 300;
    postedDebits = 25;
}

Now I'm no rocket scientist, but $100+$300-$25 = $375. My currentBalance is always $100. Also based on my sample data postedCredits & postedDebits are correct but nothing seems to be getting added to or subtracted from the initial starting balance. I'm sure I must need to type cast the results somewhere but I've tried before the fetch result gets added to the dictionary & before the addition or subtraction takes place. I've even tried [NSDecimalNumber NSDecimalNumberWithString:] after pulling them from the dictionary before operating on them.

If someone could point me in the right direction here I'd much appreciate it. Thanks in advance!!

1

There are 1 best solutions below

0
On BEST ANSWER

After looking with fresh eyes this morning I realized the answer was staring me in the face.

[totalOfTransactionsDescription setExpressionResultType:NSFloatAttributeType];

should have been

[totalOfTransactionsDescription setExpressionResultType:NSDecimalAttributeType];

That cleared it right up. :-)