Create a running sum in a UITableView - iphone

I have a UITableView populated (previously saved via a button in navbar), with transactions. Each row has five UILabel: date, description, person, value (deposits and withdraws) balance. The table is sort by date. How can I obtain the daily balance? The balance is the sum (+ and -) from the first input up to the current row.
I have the following code (JournalDetail.m), but I only get the same amount as value, instead of a cumulative amount (balance)
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = #"Cell";
GxPolizasL *cell = (GxPolizasL *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
[[NSBundle mainBundle] loadNibNamed:#"GxPolizasL" owner:self options:nil];
cell = gxPolizasL;
self.gxPolizasL = nil;
GMDiario *gmDiarioy = (GMDiario *)[self.fetchedResultsController objectAtIndexPath:indexPath];
//Date value
NSDateFormatter* df = [[NSDateFormatter alloc] init];
[df setDateFormat:#"dd/MM/yy"];
cell.fechao.text = [df stringFromDate:gmDiarioy.pzFecha];
[df release];
//Description value
cell.referencia.text=gmDiarioy.pzAlias;
//Person value
cell.item.text = gmDiarioy.persona.prAlias;
//Transaction value
NSNumberFormatter* vf = [[NSNumberFormatter alloc] init];
[vf setNumberStyle:NSNumberFormatterCurrencyStyle];
cell.valuem.text= [vf stringFromNumber: gmDiarioy.pzMont01];
[vf release];
//This is where the balance value is intended to be created
NSDecimalNumber *saldoAc = [NSDecimalNumber decimalNumberWithString:#"0.0"];
NSDecimalNumber *objectExpenseNumber = [gmDiarioy valueForKeyPath:#"pzMont01"];
saldoAc = [saldoAc decimalNumberByAdding:objectExpenseNumber];
NSLog(#"saldoAc: %#",saldoAc);
NSNumberFormatter* af = [[NSNumberFormatter alloc] init];
[af setNumberStyle:NSNumberFormatterCurrencyStyle];
cell.valuea.text= [af stringFromNumber: saldoAc];
[af release];
}
return cell;}
Could you help me to figure out which is the correct way to implement balance value? Thanks in advance. Your help is greatly appreciated.
This is the code for self.fetchedResultsController
- (NSFetchedResultsController *)fetchedResultsController
{
if (__fetchedResultsController != nil) {
return __fetchedResultsController;
}
NSFetchRequest *fetchRequest = [[[NSFetchRequest alloc] init] autorelease];
//Diario is an entity that keeps all transactions
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Diario" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
[fetchRequest setFetchBatchSize:20];
//This is to select only the journals for the current account (value passed at didSelectRowAtIndexPath from the previous UItableView
NSString *filtro=gmCuenta.cnAlias;
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"cuenta.cnAlias like %#", filtro];
NSLog(#"NSPredicate1 %#", gmDiario.cuenta);
[fetchRequest setPredicate:predicate];
NSSortDescriptor *sortDescriptor = [[[NSSortDescriptor alloc] initWithKey:#"pzFecha" ascending:YES] autorelease];
NSArray *sortDescriptors = [NSArray arrayWithObjects:sortDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
NSFetchedResultsController *aFetchedResultsController = [[[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:nil] autorelease];
aFetchedResultsController.delegate = self;
self.fetchedResultsController = aFetchedResultsController;
NSError *error = nil;
if (![self.fetchedResultsController performFetch:&error]) {
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
abort();}
return __fetchedResultsController;
}

Basically what you want to do is this: Each time cellForRowAtIndexPath: gets called you want to loop through your data source array and sum all the values starting at the beginning of the array and ending with the array item equal to the row # (i.e. indexPath.row) of the cell in question. That will give you a running total (balance).
NSDecimalNumber *saldoAc = [NSDecimalNumber decimalNumberWithString:#"0.0"];
for (int i=0; i <= indexPath.row; i++) {
NSIndexPath *indexPath = [NSIndexPath indexPathWithIndex:i];
GMDiario *tempObj = (GMDiario *)[self.fetchedResultsController objectAtIndexPath:indexPath];
NSDecimalNumber *objectExpenseNumber = [tempObj valueForKeyPath:#"pzMont01"];
saldoAc = [saldoAc decimalNumberByAdding:objectExpenseNumber];
}
NSNumberFormatter* af = [[NSNumberFormatter alloc] init];
[af setNumberStyle:NSNumberFormatterCurrencyStyle];
cell.valuea.text= [af stringFromNumber: saldoAc];
[af release];
One other comment - you should be setting the values of your cell's subviews after you exit the if (cell == nil) block. Otherwise you will run into trouble when your tableView starts scrolling.

Related

Array goes empty in DidSelectRowAtIndexPath

I have in my coreDatabase an entity "Day". In a method I fetch the data from that entity and put it in a mutuableArray dayObjects. You can see the code over here.
NSManagedObjectContext *context = [RKManagedObjectStore defaultStore].persistentStoreManagedObjectContext;
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:#"Day"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:
#"p_date >= %# and p_date <= %#",dateString,dateString2];
[fetchRequest setPredicate:predicate];
NSSortDescriptor *descriptor = [NSSortDescriptor sortDescriptorWithKey:#"p_id" ascending:YES];
fetchRequest.sortDescriptors = #[descriptor];
NSArray *matches = [context executeFetchRequest:fetchRequest error:nil];
NSLog(#"matches = %#",[matches valueForKey:#"p_date"]);
arrDateObjects = [matches mutableCopy];
In my cellForRow I do this
Day *objDay = [arrDateObjects objectAtIndex:indexPath.row-1];
Cell.titlelabel.text = day.p_from;
In my tableview the data is showed correctly. The problem is dat when I do the same thing in my DidSelectRowAtIndexPath. I always get a Null when I log day.p_from.
Can anybody help me ?
EDIT
My numberOfSections
(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
int sections = 0;
sections = 1;
return sections;
}
My numberOfRowsInSection
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
int rows = 0;
rows = 8; //showing 7 days + 1 row for a little title
return rows;
}
My CellForRowAtIndexPath
static NSString *simpleTableIdentifier = #"OpeningCell";
OpeningCell *cell = (OpeningCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"OpeningCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
if(indexPath.row == 0){
cell.lblDay.text = NSLocalizedString(#"lblDag", nil);
cell.lblFrom.text = NSLocalizedString(#"lblVan", nil);
cell.lblTill.text = NSLocalizedString(#"lblTot", nil);
}else{
Day *objDay = [arrDateObjects objectAtIndex:indexPath.row-1];
NSLog(#"Day object in cell from = %#",objDay.p_from);
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"YYYY-MM-dd"];
NSDate *date = [dateFormat dateFromString:objDay.p_date];
NSDateFormatter *dateFormat2 = [[NSDateFormatter alloc] init];
[dateFormat2 setDateFormat:#"dd/MM"];
NSString *dateString = [dateFormat2 stringFromDate:date];
NSLog(#"date: %#", dateString);
cell.lblShort.text = dateString;
cell.lblDay.text = [arrDays objectAtIndex:indexPath.row-1];
NSString *txtFrom = [objDay.p_from substringWithRange:NSMakeRange(0, 5)];
cell.lblFrom.text = txtFrom;
NSString *txtTill = [objDay.p_till substringWithRange:NSMakeRange(0, 5)];
cell.lblTill.text = txtTill;
}
return cell;
NSLog(#"matches = %#",[matches valueForKey:#"p_date"]);
arrDateObjects=[[NSMutableArray alloc]init];
[arrDateObjects addobject:[matches objectAtindex:indexpath.row-1]];
Instead of
NSLog(#"matches = %#",[matches valueForKey:#"p_date"]);
arrDateObjects = [matches mutableCopy];
//try
arrDateObjects = [NSMutableArray arrayWithArray:matches];
//instead of
arrDateObjects = [matches mutableCopy];

Core Data sectioned TableView ordered wrong

i generate a tableview using core-data and a NSFetchedResultsController with sectionNameKeyPath. My Core-Data entities look fine, also in the SQL-Database the Data looks good.
The Entity is called "Cast" and looks like this:
Cast
-> job
-> department // the attribute i want the sections from
i generate my NSFetchedResultsController like this
// fetch controller
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Cast" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
NSSortDescriptor *sort1 = [[NSSortDescriptor alloc] initWithKey:#"name" ascending:YES];
NSSortDescriptor *sort2 = [[NSSortDescriptor alloc] initWithKey:#"job" ascending:YES];
[fetchRequest setSortDescriptors:[NSArray arrayWithObjects:sort1, sort2, nil]];
[sort1 release];
[sort2 release];
// Predicate
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"movie == %#", self.movie];
[fetchRequest setPredicate:predicate];
// Generate it
NSFetchedResultsController *theFetchedResultsController =
[[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:self.managedObjectContext sectionNameKeyPath:#"department"
cacheName:nil];
self.fetchedResultsController = theFetchedResultsController;
self.fetchedResultsController.delegate = self;
[fetchRequest release];
[theFetchedResultsController release];
// Fetch Casts
NSError *error;
if (![[self fetchedResultsController] performFetch:&error]) {
// Update to handle the error appropriately.
XLog("Unresolved error %#, %#", error, [error userInfo]);
}
But the result is the following (i added the "department" attribute into the detail attribute to show the problem)
as you can see. the sections are generated properly, but then the single entities are completely random inserted into the sections.
can anybody see a bug in my code?
here is the rest of the code that is related to the cell/section stuff
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return [[self.fetchedResultsController sections] count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
id <NSFetchedResultsSectionInfo> sectionInfo = nil;
sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:section];
return [sectionInfo numberOfObjects];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell...
Cast *currentCast = [self.fetchedResultsController objectAtIndexPath:indexPath];
cell.textLabel.text = currentCast.name;
//cell.detailTextLabel.text = currentCast.job;
// just temporary
cell.detailTextLabel.text = currentCast.department;
return cell;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
NSString *jobTitle = [[[fetchedResultsController sections] objectAtIndex:section] name];
return jobTitle;
}
thanks for all hints.
please leave a comment if something is unclear.
You should sort by department first.
NSSortDescriptor *sort1 = [[NSSortDescriptor alloc] initWithKey:#"department" ascending:YES];
NSSortDescriptor *sort2 = [[NSSortDescriptor alloc] initWithKey:#"name" ascending:YES];
NSSortDescriptor *sort2 = [[NSSortDescriptor alloc] initWithKey:#"job" ascending:YES];
[fetchRequest setSortDescriptors:[NSArray arrayWithObjects:sort1, sort2, sort3, nil]];
[sort1 release];
[sort2 release];
[sort3 release];

Adding extra sections to a NSFetchedResultsController

I'm writing a small iPhone app for my company that shows bookings for each employee one week at a time. I'm using core data to get a list of 'Bookings' for a given week and want to display them in a UITableView broken down in to one section per day of the week.
The problem comes in that I need to show 7 sections for each day of the week (showing a 'No Bookings' cell where a section/date has no bookings).
I've got a screenshot of the app as it stands here (sorry can't post images yet as I'm new to StackOverlow)
At the moment I'm achieving this by using a 'fetchResults' method which gets the bookings and organises them in to an array of possible dates:
- (void)refetchResults {
// Drop bookings Array, replacing with new empty one
// 7 slots for 7 days each holding mutable array to recieve bookings where appropraite
self.bookings = [NSArray arrayWithObjects:[NSMutableArray array],
[NSMutableArray array], [NSMutableArray array],
[NSMutableArray array], [NSMutableArray array],
[NSMutableArray array], [NSMutableArray array], nil];
// Create the fetch request for the entity.
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Booking" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
// Limit to this weeks data
[fetchRequest setPredicate:
[NSPredicate predicateWithFormat:#"(date >= %#) && (date <= %#) && (resource == %#)",
firstDate,lastDate,resourceId]];
// Edit the sort key as appropriate.
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"date" ascending:YES];
NSSortDescriptor *sortDescriptor2 = [[NSSortDescriptor alloc] initWithKey:#"recId" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, sortDescriptor2, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
// Fetch records in to array
NSError *error;
NSArray *results = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
if (results == nil) {
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
abort();
}
[fetchRequest release];
[sortDescriptor release];
[sortDescriptor2 release];
[sortDescriptors release];
// Walk through records and place in bookings Array as required
for (Booking *item in results) {
// Decide on array index by difference in firstDate and booking date
int idx = (int)[[item date] timeIntervalSinceDate:firstDate]/86400;
// Add the item to the approp MutArray
[(NSMutableArray *)[bookings objectAtIndex:idx] addObject:item];
}
// Reload table
[tableView reloadData];
}
My question is: is there any way to achieve the same result using NSFetchedResultsController? Somehow I'd need to get the NSFetchedResultsController to have 7 sections, one for each day of the week, some of them possibly having no bookings.
Any help much appreciated :)
So, being as the weather isn't very nice outside I've had a go at answering my own question and implementing the 'workaround' described in my reply to westsider.
The idea is to hold a 'mapping' array (just a simple 7 slot int array) which will map the section the tableview will ask for to the underlying fetchedresultscontroller section. Each array slot will have the appropriate section index or '-1' where there are no underlying sections (and where a 'No Booking' cell should be shown instead).
So, my refetchResults method becomes:
- (void)refetchResults {
// Create the fetch request for the entity.
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Booking" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
// Limit to this weeks data
[fetchRequest setPredicate:
[NSPredicate predicateWithFormat:#"(date >= %#) && (date <= %#) && (resource == %#)",
firstDate,lastDate,resourceId]];
// Edit the sort key as appropriate.
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"date" ascending:YES];
NSSortDescriptor *sortDescriptor2 = [[NSSortDescriptor alloc] initWithKey:#"recId" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, sortDescriptor2, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
// Set up FRC
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:#"date" cacheName:nil];
self.fetchedResultsController = aFetchedResultsController;
self.fetchedResultsController.delegate = self;
[aFetchedResultsController release];
[fetchRequest release];
[sortDescriptor release];
[sortDescriptor2 release];
[sortDescriptors release];
// Run up FRC
NSError *error = nil;
if (![fetchedResultsController_ performFetch:&error]) {
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
abort();
}
// Update FRC map
[self updateFRCMap];
// Reload table
[tableView reloadData];
}
The mapping is set in the following method. This is called whenever the mapping needs to be refreshed - for example when I get callbacks from the fetchedresultscontroller for items that have been added/deleted/etc.
- (void)updateFRCMap {
// Set mapping table for seven days of week to appropriate section in frc
for (int idx=0;idx<7;idx++) { frcMap[idx] = -1; } // Reset mappings
// For each section
for (int sidx=0; sidx<[[self.fetchedResultsController sections] count]; sidx++)
{
// If section has items
if ([[[self.fetchedResultsController sections] objectAtIndex:sidx] numberOfObjects] > 0)
{
// Look at first booking of section to get date
NSDate *date = [(Booking *)[self.fetchedResultsController objectAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:sidx]] date];
// Decide on array index by difference in firstDate and booking date
int idx = (int)[date timeIntervalSinceDate:firstDate]/86400;
// Set map
frcMap[idx] = sidx;
}
}
}
This can probably be optimised a bit but works OK for now. I suspect it might suffer GMT/BST clock change problems which will need fixing ... not that clock change problems are all that urgent, eh Apple? ;P
After that it's just a case of using the mapping array when responding to the tableview:
#pragma mark -
#pragma mark Table view data source
// Gets the booking from the fetchedResultsController using a remapped indexPath
- (Booking *)bookingForMappedIndexPath:(NSIndexPath *)indexPath {
return (Booking *)[self.fetchedResultsController objectAtIndexPath:
[NSIndexPath indexPathForRow:indexPath.row inSection:frcMap[indexPath.section]]];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 7; // 7 days viewed
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Rows in section or 1 if no section
if (frcMap[section] != -1) {
id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:frcMap[section]];
return [sectionInfo numberOfObjects];
} else {
return 1;
}
}
- (UITableViewCell *)tableView:(UITableView *)_tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"RegularCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell.
[self configureCell:cell atIndexPath:indexPath];
return cell;
}
- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath {
// If no actual bookings for section then its a blank cell
if (frcMap[indexPath.section] == -1) {
// Configure a blank cell.
cell.textLabel.text = #"No Bookings";
cell.detailTextLabel.text = #"";
cell.textLabel.font = [UIFont systemFontOfSize:16];
cell.textLabel.textColor = [UIColor lightGrayColor];
cell.accessoryType = UITableViewCellAccessoryNone;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
} else {
// Regular cell
Booking *booking = [self bookingForMappedIndexPath:indexPath];
cell.textLabel.text = booking.desc;
cell.detailTextLabel.text = [NSString stringWithFormat:#"%# %#", booking.location, booking.detail];
cell.textLabel.font = [UIFont systemFontOfSize:14];
cell.textLabel.textColor = [UIColor darkTextColor];
cell.detailTextLabel.font = [UIFont systemFontOfSize:12];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cell.selectionStyle = UITableViewCellSelectionStyleBlue;
}
}
Any comments or better ways of writing this are very much welcome :)
I haven't used this much, but you might check out NSFetchedResultsSectionInfo protocol. It can be used like this, apparently:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSInteger numberOfRows = 0;
if ([[fetchedResultsController sections] count] > 0)
{
id <NSFetchedResultsSectionInfo> sectionInfo = [[fetchedResultsController sections] objectAtIndex:section];
numberOfRows = [sectionInfo numberOfObjects];
}
return numberOfRows;
}
Good luck.
I had this problem too. I've written a subclass of NSFetchedResultsController to solve the issue:
https://github.com/timothyarmes/TAFetchedResultsController
Tim

Core data setReturnsDistinctResult not working

So i'm building a small application, it uses core data database of ~25mb size with 4 entities. It's for bus timetables.
In one table named "Stop" there are ~1300 entries of bus stops with atributes "name", "id", "longitude", "latitude" and couple relationships. Now there are many stops with identical name attribute but different coordinates and id. So I want to show all distinct stop names in table view, i'm using setReturnsDistinctResults with NSDictionaryResultType and setPropertiesToFetch. But setReturnsDistinctResult is not working and I'm still getting all entries.
Heres code:
- (NSFetchRequest *)fetchRequest {
if (fetchRequest == nil) {
fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Stop" inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entity];
NSArray *sortDescriptors = [NSArray arrayWithObject:[[[NSSortDescriptor alloc] initWithKey:#"name" ascending:YES] autorelease]];
[fetchRequest setSortDescriptors:sortDescriptors];
[fetchRequest setResultType:NSDictionaryResultType];
[fetchRequest setPropertiesToFetch:[NSArray arrayWithObject:[[entity propertiesByName] objectForKey:#"name"]]];
[fetchRequest setReturnsDistinctResults:YES];
DebugLog(#"fetchRequest initialized");
}
return fetchRequest;
}
/////////////////////
- (NSFetchedResultsController *)fetchedResultsController {
if (self.predicateString != nil) {
self.predicate = [NSPredicate predicateWithFormat:#"name CONTAINS[cd] %#", self.predicateString];
[self.fetchRequest setPredicate:predicate];
} else {
self.predicate = nil;
[self.fetchRequest setPredicate:predicate];
}
fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:self.fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:sectionNameKeyPath cacheName:nil];
return fetchedResultsController;
}
//////////////
- (UITableViewCell *)tableView:(UITableView *)table cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
cell.textLabel.text = [[fetchedResultsController objectAtIndexPath:indexPath] valueForKey:#"name"];
return cell;
}
This may be late for you, but may help others.
I had the same problem. What I found is that, if persistant store type is NSSQLiteStoreType the returnDistinctResults works. But for NSXMLStoreType distinct values are not working.
I haven't tested results for NSBinaryStoreType and NSInMemoryStoreType.

Sorting Core Data with Predicate to eliminate duplicates

I have an Event database loaded into Core Data that has duplicate Event titles. This has been made so the database can provide unique information for each day of the event. Eg fluctuations in pricing on each date.
I now need to remove the duplicate event titles from a list that will be displayed as table view with NSFetchRequest and NSPredicate to provide the filter. But all the examples I've seen require a none dynamic key value to be used as a target for the predicate filter. eg below NSDate provides the time now as a key filter and it works.
Currently NSString * title targets a value in the events ManagedObject class that returns a nil value. Here is a snip from the FetchResultsController.
- (NSFetchedResultsController *)fetchedResultsController {
if (fetchedResultsController == nil) {
NSFetchRequest *fetchRequest = [[[NSFetchRequest alloc] init] autorelease];
NSPredicate *predicate = [[[NSPredicate alloc] init] autorelease];
[fetchRequest setReturnsObjectsAsFaults:NO];
[fetchRequest setEntity:[NSEntityDescription entityForName:#"Event" inManagedObjectContext:managedObjectContext]];
NSArray *sortDescriptors = nil;
NSString *sectionNameKeyPath = nil;
NSDate *date = [NSDate date];
NSString *title = [events title];
if ([fetchSectioningControl selectedSegmentIndex] == 1) {
predicate = [NSPredicate predicateWithFormat:#"(closeDate >= %#) AND (title == %#)", date, title ];
sortDescriptors = [NSArray arrayWithObjects:[[[NSSortDescriptor alloc] initWithKey:#"category.name" ascending:YES] autorelease], [[[NSSortDescriptor alloc] initWithKey:#"openDate" ascending:YES] autorelease], nil];
sectionNameKeyPath = #"category.name";
} else if ([fetchSectioningControl selectedSegmentIndex] == 0){
predicate = [NSPredicate predicateWithFormat:#"closeDate >= %#", date];
sortDescriptors = [NSArray arrayWithObject:[[[NSSortDescriptor alloc] initWithKey:#"openDate" ascending:YES selector:#selector(compare:)] autorelease]];
sectionNameKeyPath = #"day";
}
[fetchRequest setPredicate:predicate];
[fetchRequest setSortDescriptors:sortDescriptors];
fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:sectionNameKeyPath cacheName:#"EventsCache"];
}
return fetchedResultsController;
}
You could set
setReturnsDistinctResults:YES
on your fetchRequest.
For more, see the docs:
NSFetchRequest Class Reference