I have encountered a problem of placing data into the Table View. Here is my current code.
I am unable to load the results from the class I tried to use NSFetchedResultsController, but it won’t work. Can any one see the mistake.
This is the header file.
#import <UIKit/UIKit.h>
#import <CoreData/CoreData.h>
#import <sqlite3.h>
#import "FlickrFetcher.h"
@interface PersonList : UITableViewController {
FlickrFetcher *fetcher;
NSArray *nameList;
NSArray *names;
NSFetchedResultsController *results;
NSArray *photos;
}
@property (retain, nonatomic)NSArray *nameList;
@property (retain, nonatomic)NSArray *names;
@property (retain, nonatomic)NSArray *photos;
@property (retain, nonatomic)NSFetchedResultsController *results;
@end
This is the .m file.
#import "PersonList.h"
@implementation PersonList
@synthesize nameList,names,results,photos;
// The designated initializer. Override if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
self.title=@"Contacts";
// Custom initialization
}
return self;
}
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
fetcher = [FlickrFetcher sharedInstance];
NSString *path=[[NSBundle mainBundle]pathForResource:@"FakeData" ofType:@"plist"];
NSArray *array=[NSArray arrayWithContentsOfFile:path];
NSManagedObjectContext *context=[fetcher managedObjectContext];
if([fetcher databaseExists]==YES){
for(NSDictionary *dic in array){
PersonList *person=(PersonList *)[NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:context];
[person setNameList:[dic objectForKey:@"user"]];
[person setPhotos:[dic objectForKey:@"path"]];
names=[fetcher fetchManagedObjectsForEntity:@"Person" withPredicate:nil];
results=[fetcher fetchedResultsControllerForEntity:@"Person" withPredicate:nil];
}
}
[super viewDidLoad];
}
/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
self.names=nil;
}
- (void)dealloc {
[fetcher release];
[nameList release];
[super dealloc];
}
#pragma mark -
#pragma mark Table View Data Source Methods
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [[results sections] count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(@"NOT REACHED HERE");
static NSString *SimpleTableIdentifier = @"SimpleTableIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:
SimpleTableIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:SimpleTableIdentifier] autorelease];
}
NSUInteger row = [indexPath row];
cell.textLabel.text = [[results sections] objectAtIndex:row];
return cell;
}
@end
This the method for the FlickrFetcher method
#import <UIKit/UIKit.h>
#import <CoreData/CoreData.h>
@interface FlickrFetcher : NSObject {
NSManagedObjectModel *managedObjectModel;
NSManagedObjectContext *managedObjectContext;
NSPersistentStoreCoordinator *persistentStoreCoordinator;
}
// Returns the 'singleton' instance of this class
+ (id)sharedInstance;
// Checks to see if any database exists on disk
- (BOOL)databaseExists;
// Returns the NSManagedObjectContext for inserting and fetching objects into the store
- (NSManagedObjectContext *)managedObjectContext;
// Returns an array of objects already in the database for the given Entity Name and Predicate
- (NSArray *)fetchManagedObjectsForEntity:(NSString*)entityName withPredicate:(NSPredicate*)predicate;
// Returns an NSFetchedResultsController for a given Entity Name and Predicate
- (NSFetchedResultsController *)fetchedResultsControllerForEntity:(NSString*)entityName withPredicate:(NSPredicate*)predicate;
@end
[super viewDidLoad]before your code. The only time a call to super should be after your code is in the-deallocmethod.NSFetchedResultsControllerand doing nothing with it. You are not even keeping a reference. This is incorrect. You should have ONENSFetchedResultsControllerperUITableViewController; you should retain reference to it; yourUITableViewDatasource(which in this case is yourUITableViewController) should be its delegate.-performFetch:on theNSFetchedResultsControllerso there is no data being retrieved.NSFetchedResultsControlleryou would have no way of knowing when it got data back anyway because that is the singular way that it communicates data changes.I would reconsider your design and review the Core Data iPhone sample projects again.
Update
The
NSFetchedResultsControllerdoes not fire its delegate methods until you save theNSManagedObjectContextso that is why you are not seeing data.As for the error you are getting, you are trying to set a property on an object that does not respond to that property. I would suggest loading your application into the debugger, putting a breakpoint on
objc_exception_throwand see what object you are manipulating that is causing the problem. Most likely you are getting back one object and thinking it is another.