NSFetchedResultsController with NSPredicate in Two Different UIViewControllers - NSRangeException - ios

I have two different views, controlled by two different view controllers. Each view has a UITableView inside it. Each UITableView is hooked to a NSFetchedResultsController. In View 1, I do not want to narrow my FRC results, so I do not use a predicate. In View 2, I use a predicate to get certain objects based on a BOOL (aka NSNumber!) value. But when I try to use this predicate, I get an NSRangeException (index 1 beyond bounds) when I segue to View 2. It also throws that exception when I switch the predicates (predicate on View 1, no predicate on View 2). And again the exception comes when I segue to View 2. There are cases where it is successful (neither of which is what I want):
1) I do not use any predicate for either fetch request.
2) I use the same predicate for the fetch request for both View 1 and View 2.
Some code for your enjoyment:
In View1.m:
-(NSFetchedResultsController *)fetchedResultsController {
if (_fetchedResultsController != nil) {
return _fetchedResultsController;
}
NSManagedObjectContext *context = [CoreDataHelper getContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription
entityForName:#"EditableSong" inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSSortDescriptor *sort = [[NSSortDescriptor alloc]
initWithKey:#"dateModified" ascending:NO];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]];
[fetchRequest setFetchBatchSize:5];
NSFetchedResultsController *theFetchedResultsController =
[[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:context sectionNameKeyPath:nil
cacheName:#"Root"];
self.fetchedResultsController = theFetchedResultsController;
_fetchedResultsController.delegate = self;
return _fetchedResultsController;
}
In View2.m
-(NSFetchedResultsController *)fetchedResultsController {
if (_fetchedResultsController != nil) {
return _fetchedResultsController;
}
NSManagedObjectContext *context = [CoreDataHelper getContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription
entityForName:#"EditableSong" inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSSortDescriptor *sort = [[NSSortDescriptor alloc]
initWithKey:#"dateModified" ascending:NO];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]];
NSPredicate *myPredicate = [NSPredicate predicateWithFormat:#"collaborative == %#", [NSNumber numberWithInt:0]];
[fetchRequest setPredicate:myPredicate];
[fetchRequest setFetchBatchSize:5];
NSFetchedResultsController *theFetchedResultsController =
[[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:context sectionNameKeyPath:nil
cacheName:#"Root"];
NSLog(#"here");
self.fetchedResultsController = theFetchedResultsController;
_fetchedResultsController.delegate = self;
return _fetchedResultsController;
}
And this is where the green error arrow (SIGABRT) points to (this code is the same in View1 and View2 by the way):
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *MyIdentifier = [NSString stringWithFormat:#"MyIdentifier %i", indexPath.row];
SongTableViewCell *cell = (SongTableViewCell *)[tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil) {
EditableSong *song = [_fetchedResultsController objectAtIndexPath:indexPath];//<<<------HERE!!! SIGABRT
song.audioPlayer = [[AudioPlayer alloc] initWithSong:song];
cell = [[SongTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier editableSong:song andVC:self];
UIButton *playButton = [UIButton buttonWithType:UIButtonTypeCustom];
[playButton setBackgroundColor:[UIColor clearColor]];
[playButton setImage:[UIImage imageNamed:#"mainmenuplay.png"] forState:UIControlStateNormal];
playButton.frame = CGRectMake(300.0f, 15.0f, 65.0f, 65.0f);
[playButton addTarget:self action:#selector(playSong:) forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview:playButton];
}
return cell;
}
Thanks!
Update 1
Here is my numberOfRowsInSection method (again, same for both classes):
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
id sectionInfo =
[[_fetchedResultsController sections] objectAtIndex:section];
NSLog(#"%i", [sectionInfo numberOfObjects]);
return [sectionInfo numberOfObjects];
}
For reference, that log is supposed to print 3 in View1 and 1 in View2, but it prints 3 in both.

It seems you are returning the wrong number of cells. cellForRowAtIndexPath: wants to create a cell, but there is no objectAtIndexPath.
So you will need to check your numberOfRowsInSection method.

Problem solved:
Had to change the cache to nil.
See this post:
http://iphoneincubator.com/blog/data-management/delete-the-nsfetchedresultscontroller-cache-before-changing-the-nspredicate

Related

iOS, group table view, grouped by one core data entity

I have (order) table View controller, sorted by "code" entity
What I want to do is a grouped table view, grouped by
order.customer.name to be like this
[customer one]
*order.code1 - product1
*order.code2 - product1
[customer two]
...
What I have right know in viewWillAppear is:
- (void)viewWillAppear:(BOOL)animated{
NSEntityDescription *orderDescription = [NSEntityDescription entityForName: #"Order"
inManagedObjectContext:self.context];
NSFetchRequest *request = [NSFetchRequest new];
[request setEntity:orderDescription];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"code" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[request setSortDescriptors:sortDescriptors];
self.controller = [[NSFetchedResultsController alloc]
initWithFetchRequest:request
managedObjectContext:self.context
sectionNameKeyPath:nil
cacheName:nil];
NSError *error;
[self.controller performFetch:&error];
}
this might be usefull as well
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell" forIndexPath:indexPath];
// Configure the cell...
NSManagedObject *managedObject = [self.controller objectAtIndexPath:indexPath];
cell.textLabel.text = ((Order *) managedObject).code;
cell.detailTextLabel.text = ((Order *) managedObject).product.name;
return cell;
}
I found some solutions for group table view, but most of it isn't for core data
Thanks
Is this what you want?
- (void)setupFetch:(NSManagedObjectContext*)context {
NSEntityDescription *orderDescription = [NSEntityDescription entityForName: #"Order"
inManagedObjectContext:context];
NSFetchRequest *request = [NSFetchRequest new];
[request setEntity:orderDescription];
NSSortDescriptor *sortDescriptorSection = [[NSSortDescriptor alloc] initWithKey:#"customer.name" ascending:YES];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"code" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptorSection, sortDescriptor, nil];
[request setSortDescriptors:sortDescriptors];
self.controller = [[NSFetchedResultsController alloc] initWithFetchRequest:request
managedObjectContext:context
sectionNameKeyPath:#"customer.name"
cacheName:nil];
NSError *error;
[self.controller performFetch:&error];
[self.tableView reloadData];
}
That should create groups based on customer name but sort according to code.
Edit: To clarify. You want to use the sectionNameKeyPath to achieve what you want. Note that you need to use the sections in the NSFetchedResultsController something like so:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
id <NSFetchedResultsSectionInfo> sectionInfo = [self.controller.sections objectAtIndex:section];
return [sectionInfo numberOfObjects];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return [self.controller.sections count];
}
I have a similar case for Rooms and Devices. My sections are Rooms and my cells are Devices, sorted first my RoomName and then by DeviceName
- (NSFetchedResultsController *)fetchedResultsController
{
if( !fetchedResultsController )
{
// Create the fetch request for the entity.
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
// Edit the entity name as appropriate.
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Device"
inManagedObjectContext:del.managedObjectContext];
[fetchRequest setEntity:entity];
// Edit the sort key as appropriate. This will sort the sections (setting this attribute as sectionNameKeyPath)
NSSortDescriptor *sortDescriptor1 = [[NSSortDescriptor alloc] initWithKey:#"room.roomName" ascending:YES selector:#selector(localizedCaseInsensitiveCompare:)];
NSSortDescriptor *sortDescriptor2 = [[NSSortDescriptor alloc] initWithKey:#"deviceName" ascending:YES selector:#selector(localizedCaseInsensitiveCompare:)];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor1, sortDescriptor2, nil];
[sortDescriptor1 release];
[sortDescriptor2 release];
[fetchRequest setSortDescriptors:sortDescriptors];
NSPredicate* predicate = ...; // selecting devices by filter
[fetchRequest setPredicate:predicate];
// Edit the section name key path and cache name if appropriate.
// nil for section name key path means "no sections".
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:managedObjectContext
sectionNameKeyPath:#"room.roomName"
cacheName:nil];
aFetchedResultsController.delegate = self;
self.fetchedResultsController = aFetchedResultsController;
[aFetchedResultsController release];
[fetchRequest release];
[sortDescriptors release];
}
return fetchedResultsController;
}
this is used like following:
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
NSError *error = nil;
if( ![[self fetchedResultsController] performFetch:&error] )
{
// do error handling
abort();
}
[self.tableView reloadData];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
int nor = [[fetchedResultsController sections] count];
return nor;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
// I have a Translation class for internationalisation
return [Translation forKey:[[[fetchedResultsController sections] objectAtIndex:section] name]];
}
- (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;
}
and using in the cell like
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
Device *device = [fetchedResultsController objectAtIndexPath:indexPath];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:...];
if( !cell )
{
cell = ...
// and so on
}
return cell;
}

Core Data Entity Search Using NSPredicate

I have an app that saves data to a Core Data sql then view it in a tableView. And I'm trying to add a searchBar to search through the data.
I created two NSFetchedResultsController. One for getting entity data and the other for getting entity data after filtering using NSPredicate.
- (NSFetchedResultsController *)fetchedResultsController {
if (_fetchedResultsController != nil) {
return _fetchedResultsController;
}
CoreDataStack *coreDataStack = [CoreDataStack DefaultStack];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"offer" inManagedObjectContext:coreDataStack.managedObjectContext];
[fetchRequest setEntity:entity];
fetchRequest.sortDescriptors = #[[NSSortDescriptor sortDescriptorWithKey:#"date" ascending:NO]];
_fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:coreDataStack.managedObjectContext sectionNameKeyPath:#"sectionName" cacheName:nil];
_fetchedResultsController.delegate = self;
return _fetchedResultsController;
}
- (NSFetchedResultsController *)fetchedSearchResultsController{
if (_fetchedSearchResultsController != nil) {
return _fetchedSearchResultsController;
}
CoreDataStack *coreDataStack = [CoreDataStack DefaultStack];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"offer" inManagedObjectContext:coreDataStack.managedObjectContext];
[fetchRequest setEntity:entity];
fetchRequest.sortDescriptors = #[[NSSortDescriptor sortDescriptorWithKey:#"date" ascending:NO]];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"location contains[c] %#", self.searchDisplayController.searchBar.text];
[fetchRequest setPredicate:predicate];
_fetchedSearchResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:coreDataStack.managedObjectContext sectionNameKeyPath:#"sectionName" cacheName:nil];
_fetchedSearchResultsController.delegate = self;
return _fetchedSearchResultsController;
}
And showing data in each cell by cellForRowAtIndexPath:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];//] forIndexPath:indexPath];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
Entry *entry = [self.fetchedResultsController objectAtIndexPath:indexPath];
Entry *searchEntry = [self.fetchedSearchResultsController objectAtIndexPath:indexPath];
NSString *recipe = nil;
if (tableView == self.searchDisplayController.searchResultsTableView) {
cell.textLabel.text = searchEntry.location;
} else {
cell.textLabel.text = entry.location;
}
return cell;
}
But I get this error: *'NSRangeException', reason: '* -[__NSArrayM objectAtIndex:]: index 0 beyond bounds for empty array'*
When I comment [fetchRequest setPredicate:predicate]; out, I don't get the error anymore. So I'm assuming the error is coming from predicate but I don't know how to overcome it.
Entry *entry = [self.fetchedResultsController objectAtIndexPath:indexPath];
Entry *searchEntry = [self.fetchedSearchResultsController objectAtIndexPath:indexPath];
first check for entry and searchEntry wether returning null or not ?

Logic issues with numberOfItemsInSection:

I'm trying to make my own version of this tutorial here (UICollectionView inside UITableViewCell): http://ashfurrow.com/blog/putting-a-uicollectionview-in-a-uitableviewcell
I'm having difficulties getting the correct count of UICollectionViewCells in each UITableViewCell:
The first cell is correct, it should have two UICollectionViewCells inside the UICollectionView (which of course, is inside a UITableViewCell). The second is what is throwing me up. Every time I make a new save in Core Data, it will add it to the previous cells. The second cell should have one UICollectionViewCell, not two UICollectionViewCells.
Here's my code (the code for AFTableViewCell & AFIndexedCollectionView can be found on the above tutorial link):
The numberOfItemsInSection: for the UICollectionView embedded in the UITableViewCell:
- (NSInteger)collectionView:(AFIndexedCollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
NSIndexPath *indexPath;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Group" inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entity];
NSSortDescriptor *urlDescriptor = [[NSSortDescriptor alloc] initWithKey:#"url" ascending:NO];
NSArray *sortDescriptors = nil;
sortDescriptors = [[NSArray alloc] initWithObjects:urlDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
NSError *error = nil;
NSArray *fetchedObjects = [[managedObjectContext executeFetchRequest:fetchRequest error:&error]objectAtIndex:indexPath.section];
NSString *temp = [fetchedObjects description];
NSArray *tempArg = [temp componentsSeparatedByString:#","];
return [tempArg count];
}
The numberOfSectionsInTableView: for the main UITableView:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
id <NSFetchedResultsSectionInfo> sectionInfo = nil;
NSIndexPath *section;
sectionInfo = [[fetchedResultsController sections] objectAtIndex:section.section];
return [sectionInfo numberOfObjects];
}
The NSFetchedResultsController:
- (NSFetchedResultsController *)fetchedResultsController
{
TBAppDelegate *delegate = (TBAppDelegate *)[[UIApplication sharedApplication] delegate];
self.managedObjectContext = delegate.managedObjectContext;
NSFetchRequest *fetchRequest = nil;
fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = nil;
entity = [NSEntityDescription entityForName:#"Group" inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entity];
[fetchRequest setFetchBatchSize:INFINITY];
NSSortDescriptor *urlDescriptor = [[NSSortDescriptor alloc] initWithKey:#"name" ascending:NO];
NSArray *sortDescriptors = nil;
sortDescriptors = [[NSArray alloc] initWithObjects:urlDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
NSFetchedResultsController *frc = nil;
frc = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:[self managedObjectContext] sectionNameKeyPath:nil cacheName:#"Root"];
[frc setDelegate:self];
[self setFetchedResultsController:frc];
return frc;
}
The UITableView cellForRowAtIndexpath:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"CellIdentifier";
AFTableViewCell *cell = (AFTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell)
{
cell = [[AFTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
return cell;
}
Thanks in advance.
Use
NSArray *fetchedObjects = [[managedObjectContext executeFetchRequest:fetchRequest error:&error]objectAtIndex:section];
instead of
NSArray *fetchedObjects = [[managedObjectContext executeFetchRequest:fetchRequest error:&error]objectAtIndex:indexPath.section];
in your - (NSInteger)collectionView:(AFIndexedCollectionView *)collectionView numberOfItemsInSection:(NSInteger)section function on line 10
It seems the IndexPath local variable is not initialized in this function. You can get section from the parameter passed.
and you haven't initialized section local variable in your
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
function.
If you do not initialize this variables and use them, they return a garbage value or crashes the program. be careful in these kind of access.

How to know type of NSManagedObject in NSManagedContext

I am using NSFetchedResultsController to fetch data from Core Data and to show them in UITableView. My NSFetchedResultsController looks like this:
- (NSFetchedResultsController *) fetchedResultsController
{
if (_fetchedResultsController != nil)
{
return _fetchedResultsController;
}
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"PlanPreparation"
inManagedObjectContext:_context];
[fetchRequest setEntity:entity];
NSPredicate *pred = [NSPredicate predicateWithFormat:#"plan_id == %#", _planCycleID];
[fetchRequest setPredicate:pred];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"name" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects: sortDescriptor, nil];
fetchRequest.sortDescriptors = sortDescriptors;
_fetchedResultsController = [[NSFetchedResultsController alloc]initWithFetchRequest:fetchRequest managedObjectContext:_context sectionNameKeyPath:nil cacheName:nil];
_fetchedResultsController.delegate = self;
// but if there is no results I am making another fetch by another type of NSManagedObject
if (_fetchedResultsController.fetchedObjects.count == 0)
{
NSFetchRequest *fetchRequest1 = [[NSFetchRequest alloc] init];
NSEntityDescription *entity1 = [NSEntityDescription entityForName:#"Preparation"
inManagedObjectContext:_context];
[fetchRequest1 setEntity:entity1];
NSPredicate *pred = [NSPredicate predicateWithFormat:#"ismer == %#", [NSNumber numberWithInt:1]];
[fetchRequest1 setPredicate:pred];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"name" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects: sortDescriptor, nil];
fetchRequest1.sortDescriptors = sortDescriptors;
_fetchedResultsController = [[NSFetchedResultsController alloc]initWithFetchRequest:fetchRequest1 managedObjectContext:_context sectionNameKeyPath:nil cacheName:nil];
_fetchedResultsController.delegate = self;
//return _fetchedResultsController;
}
return _fetchedResultsController;
}
If I am not retreiving something after first attempt to fetch, I need to set another fetch. In -cellForRowAtIndexPath I need to show data depends on type of NSManagedObjectObject:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
if ([[self.fetchedResultsController objectAtIndexPath:indexPath] isKindOfClass:[PlanPreparation2 class]])
{
PlanPreparation2 *planDrug = (PlanPreparation2 *)[self.fetchedResultsController objectAtIndexPath:indexPath];
CDPreparation *prep = (CDPreparation *)[[PTDataManager sharedManager]getDrugByID:planDrug.guid];
cell.textLabel.text = [NSString stringWithFormat:#"%#", prep.name];
}
else
{
CDPreparation *drug = (CDPreparation *)[self.fetchedResultsController objectAtIndexPath:indexPath];
cell.textLabel.text = [NSString stringWithFormat:#"%#", drug.name];
}
return cell;
}
but logging shows that -isKindOfClass: don't work here, I am not getting into quotes at all.
Question:
How can I find out type of NSManagedObjectObject?
as shown in the picture change the name and class in data model inspector of that entity
name and class field in data model inspector must be same as name of entity table.
and then after you can compare like
if([(NSManagedObject *)[self.fetchedResultsController objectAtIndexPath:indexPath] isKindOfClass:[Category class]])
as "category" is the class in my case you can choose your own as you write above [PlanPreparation2 class]
if still you face problem then comment below

Can't fetch number of cells in tableView

I have a main tableViewController, touch a button self.navigation will push addItem viewController, click save self.navigation with pop the add VC, then we're back on the main one, I successfully add and save, also fetch, but when it comes to fetching number of cells, number returns 0, heres the method
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
id <NSFetchedResultsSectionInfo> secInfo = [[self.fetchedResultsController sections] objectAtIndex:section];
NSLog(#"No. of cells determined: %lu", (unsigned long)[secInfo numberOfObjects]);
return[secInfo numberOfObjects];
}
NSLog gives me 0, whats the problem, this gave me headache.
Here's the fetch request:
- (NSFetchedResultsController*) fetchedResultsController {
// Fetch Request
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Goal"
inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"title"
ascending:NO];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
// setting _fethcedResultsController
_fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:self.managedObjectContext
sectionNameKeyPath:nil
cacheName:nil];
// setting _fetchedResultsController to self
_fetchedResultsController.delegate = self; // for the tableview updating thing
// Thats it
return _fetchedResultsController;
}
Please note that when I run a check for items, it's not nil:
// fetching all items to check how many of them exists
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity: [NSEntityDescription entityForName:#"Goal"
inManagedObjectContext:self.managedObjectContext]];
NSManagedObjectContext *moc = self.managedObjectContext;
NSError *fetchError = nil;
NSArray *goals = [moc executeFetchRequest:fetchRequest error:&fetchError];
NSLog(#"No. of goals: %lu", (unsigned long)[goals count]);
// end of check for items
I forgot to put this code of line:
if (_fetchedResultsController != nil) {
return _fetchedResultsController;
}
in method
- (NSFetchedResultsController*) fetchedResultsController;
so before I did, the app always creates new fetchedResultsController and over-write the old one.

Resources