2

I have a fetchedResultsController using CoreDataTableView that I want to retrieve information from, the problem is that I am not getting any values from the fetchedresultsController, I believe that the values are stored into CoreDataProperly but I dont think I am retrieving them properly. I have a separate file that stores all the data and I have a class method that should pass back the context of the NSManagedObject, I think the problem may be here. I am storing an certain values of an NSDictionary such as the title and id and the image. Here is the code

#import "FlickrVacationViewController.h"
#import "FlickrCoreDataProcess.h"
#import "VacationPhoto+Flickr.h"

@interface FlickrVacationViewController ()
@end

@implementation FlickrVacationViewController

-(void) setupFetchedResultsController{

NSFetchRequest * request = [NSFetchRequest fetchRequestWithEntityName:@"VacationPhoto"];
request.sortDescriptors = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"title" ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)]];

//[FlickrCoreDataProcess shareManagedObject] should share the NSManagedObject
//performFetch gets called here
self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:[FlickrCoreDataProcess shareManagedObject].managedObjectContext sectionNameKeyPath:nil cacheName:nil];

NSLog(@"Number of Objects = %i", [[self.fetchedResultsController fetchedObjects] count]);
//This returns 0

NSLog(@"temp array is %@",self.fetchedResultsController.fetchedObjects);
//Array is empty?
}

- (void)viewDidLoad
{
[super viewDidLoad];

[self setupFetchedResultsController];
}

- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}

//This is not called, I think since the fetchedResultsController doesnt have any values
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Vacation Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

// Configure the cell...

VacationPhoto  *vacationPhoto = [self.fetchedResultsController objectAtIndexPath:indexPath];
NSLog(@"text = %@", vacationPhoto.title);
cell.textLabel.text = vacationPhoto.title;

return cell;
}

@end

This is the file that stores the data here is the method to pass the NSManagedObject

+(UIManagedDocument*) shareManagedObject{

NSURL* url  = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
url = [url URLByAppendingPathComponent:@"Default Photo DataBase"];

static UIManagedDocument *doc = nil;

static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
    doc = [[UIManagedDocument alloc] initWithFileURL:url];
});

return doc;

}

And Here is how I store the file

+(VacationPhoto*) photoWithFlickrInfo: (NSDictionary*) flickrInfo inManagedObjectContext: (NSManagedObjectContext*) context{

NSLog(@"Photo To Store =%@", flickrInfo);   
VacationPhoto * photo = nil;

NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"VacationPhoto"];
request.predicate = [NSPredicate predicateWithFormat:@"uniqueID = %@", [flickrInfo objectForKey:FLICKR_PHOTO_ID]];
NSSortDescriptor * descriptor = [NSSortDescriptor sortDescriptorWithKey:@"title" ascending:YES];
request.sortDescriptors = [NSArray arrayWithObject:descriptor];

NSError *error = nil;
NSArray *matches =  [context executeFetchRequest:request error:&error];

if (!matches || [matches count] > 1) {
    // handle error
} else if ( [matches count] == 0){
    photo = [NSEntityDescription insertNewObjectForEntityForName:@"VacationPhoto" inManagedObjectContext:context];
    photo.placeName = [flickrInfo objectForKey:FLICKR_PHOTO_PLACE_NAME];
    photo.title = [flickrInfo objectForKey:FLICKR_PHOTO_TITLE];
    NSLog(@"title = %@", photo.title);
    photo.uniqueID = [flickrInfo objectForKey:FLICKR_PHOTO_ID];
    NSLog(@"ID = %@", photo.uniqueID);
    photo.imgURL = [[FlickrFetcher urlForPhoto:flickrInfo format:FlickrPhotoFormatLarge] absoluteString];

} else {
    photo = [matches lastObject];
}

return photo;

}

May have not mentioned this but I created a UITableViewController first and then made it a subclass of CoreDataTableViewController so performFetch and other functions like that should be called from that.

Terrel Gibson
  • 481
  • 1
  • 6
  • 21
  • I think the problem is when I setup the fetchedResultsController, I think passing the context doesnt work, I just dont know how to fix it if it is, how would I pass a context between files? – Terrel Gibson Sep 07 '12 at 04:56

2 Answers2

0

Seems like you forgot about calling -[NSManagedObjectContext save:] to actually save the objects you insert.

Jeff
  • 5,013
  • 1
  • 33
  • 30
  • After The storeFile Is called I call this right after [document saveToURL:document.fileURL forSaveOperation:UIDocumentSaveForOverwriting completionHandler:NULL]; – Terrel Gibson Sep 06 '12 at 03:01
0

You seem to be missing a call to performFetch and also the data source method that tells the table how many rows are in each section.

Phillip Mills
  • 30,888
  • 4
  • 42
  • 57
  • I created a UITableViewController first and then made it a subclass of CoreDataTableViewController so performFetch and other functions like that should be called from that. – Terrel Gibson Sep 06 '12 at 03:05
  • Whatever you may inherit from, you're still calling `initWithFetchRequest:` and then expecting the controller to have valid results immediately without telling it to fetch anything. – Phillip Mills Sep 06 '12 at 11:26
  • when initWithFetchRequest is called the CoreDataTableView file gets called and in there performFetch is called, do I have to set up the fetchedResultsController before I input data? Or can I input data and then call the fetchedResultsController after and get it? – Terrel Gibson Sep 06 '12 at 20:04
  • Have you put a breakpoint on the call to performFetch to **verify** that's happening as you describe? (I'm wondering because it sounds magical, in that you're not passing the fetched results controller to any other object that could use it.) – Phillip Mills Sep 06 '12 at 21:08
  • yes I have a break point in performFetch and it does get called, I am not entirely sure how it gets called but when initWithFetchRequest gets called the CoreDataTableView gets called and does perform fetch – Terrel Gibson Sep 07 '12 at 01:10