I am developing small application in iOS (I am complete beginner). I have made a menu Core Data entity where I have categoryName
and imageNamed
saved. I want my UICollectionView
in sections. But I am stuck in defining different indexPath
s for different sections.
I also feel that my way of accessing data is very poor and seems inefficient as I am defining two NSFetchedResultsController
instances. How can I access the data store better?
I get this error:
14-03-17 10:02:19.974 citiliving[1149:70b] * Terminating app due to uncaught exception 'NSRangeException', reason: '* -[__NSArrayM objectAtIndex:]: index 1 beyond bounds [0 .. 0]'
Error seems is out of bound so section is accessing something that is not in array boundaries.
Code to access data in viewDidLoad
:
- (void)viewDidLoad
{
[super viewDidLoad];
testAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext *managedObjectContext = [appDelegate managedObjectContext];
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Menu"];
NSString *cacheName = [@"Menu" stringByAppendingString:@"Cache"];
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"categoryName" ascending:YES];
NSPredicate* pred = [NSPredicate predicateWithFormat:@"section = %@", @"dining"];
fetchRequest.predicate = pred; // req is the NSFetchRequest we're configuring
[fetchRequest setSortDescriptors:@[sortDescriptor]];
self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:nil cacheName:cacheName ];
NSError *error;
if (![self.fetchedResultsController performFetch:&error])
{
NSLog(@"Fetch failed: %@", error);
}
else
{
NSLog(@"Records found: number %lu", (unsigned long)self.fetchedResultsController.fetchedObjects.count);
}
NSFetchRequest *fetchRequestMenuTwo = [NSFetchRequest fetchRequestWithEntityName:@"Menu"];
NSString *cacheNameTwo = [@"Menu" stringByAppendingString:@"Cache"];
NSSortDescriptor *sortDescriptorTwo = [NSSortDescriptor sortDescriptorWithKey:@"categoryName" ascending:YES];
NSPredicate* predTwo = [NSPredicate predicateWithFormat:@"section = %@", @"information"];
fetchRequestMenuTwo.predicate = predTwo; // req is the NSFetchRequest we're configuring
[fetchRequestMenuTwo setSortDescriptors:@[sortDescriptorTwo]];
self.fetchedResultsControllerTwo = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequestMenuTwo managedObjectContext:managedObjectContext sectionNameKeyPath:nil cacheName:cacheNameTwo ];
//NSError *error;
if (![self.fetchedResultsControllerTwo performFetch:&error])
{
NSLog(@"Fetch failed: %@", error);
}
else
{
NSLog(@"Records found at 2nd fetch: number %lu", (unsigned long)self.fetchedResultsControllerTwo.fetchedObjects.count);
}
}
Note: I wanted to create object in variable which I can easily access in further code but I tried all variable could not do it.
Code used to get sections:
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
switch (section) {
case 0:
return self.fetchedResultsController.fetchedObjects.count;
case 1:
return self.fetchedResultsControllerTwo.fetchedObjects.count;
default:
return 0;
}
}
-(NSString *)nameForSection:(NSInteger)index
{
switch(index)
{
case 0:
return @"Section One";
case 1:
return @"Section Two";
default:
return @"Unknown";
}
}
Finally getting everything in indexPath
(here I am getting error as soon as I put 2nd section coding otherwise first section running ok:
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *identifier = @"Cell";
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];
switch (indexPath.section) {
case 0:
{
Menu *menu = (Menu *)[self.fetchedResultsController objectAtIndexPath:indexPath];
UIImageView *cityLivingImageView = (UIImageView *)[cell viewWithTag:100];
UILabel *cityLivingLabel = (UILabel *)[cell viewWithTag:200];
cityLivingLabel.text = menu.categoryName;
cityLivingImageView.image = [UIImage imageNamed:menu.imageName];
NSLog(@"Record found: %@", menu.categoryName );
return cell;
}
case 1:
{
Menu *menu = (Menu *)[self.fetchedResultsControllerTwo objectAtIndexPath:indexPath];
UIImageView *cityLivingImageView = (UIImageView *)[cell viewWithTag:100];
UILabel *cityLivingLabel = (UILabel *)[cell viewWithTag:200];
cityLivingLabel.text = menu.categoryName;
cityLivingImageView.image = [UIImage imageNamed:menu.imageName];
NSLog(@"Record found: %@", menu.categoryName );
return cell;
}
default:
break;
}
return cell;
}
I have only two sections and one has 5 rows and other have 6 rows. I wanted to make this one controller to access data and put everything in variables so later I can use variables. My database is categoryName | categoryImage | section
where section identify section one and two so I use predicate to make two different section using section field value.