vikmalhotra
vikmalhotra

Reputation: 10071

Core Data: Issue in fetching data from sqlite database

I am trying to get some data displayed in a table view which is a part of a view controller in a tabbar controller. Currently I am tring to run the app on iPhone Simulator. I copied the sqlite database to the following location - /Users/{username}/Library/Application Support/iPhoneSimulator/4.2/Applications/{appid}/Documents

Now I am trying to fetch the data in viewWillAppear method of my view controller.

#import "FugitivesViewController.h"    
#import "MyAppDelegate.h"

#import "Fugitive.h"

- (void)viewWillAppear:(BOOL)animated {
        [super viewWillAppear:animated];
        NSManagedObjectContext *context = [(MyAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
        NSFetchRequest *request = [[NSFetchRequest alloc] init];
        NSEntityDescription *entity = [NSEntityDescription entityForName:@"Fugitive" inManagedObjectContext:context];
        [request setEntity:entity];

        NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
        NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
        [request setSortDescriptors:sortDescriptors];
        [sortDescriptors release];
        [sortDescriptor release];

        NSError *error = nil;
        NSMutableArray *mutableFetchResults = [[context executeFetchRequest:request error:&error] mutableCopy];

        if (mutableFetchResults == nil) {
            NSLog(@"Error while fetching the results");
        }

        self.items = mutableFetchResults;

        [mutableFetchResults release];
        [error release];

        [request release];
        [context release];
    }

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    // Return the number of rows in the section.
    return [self.items count];
}

- (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] autorelease];
    }
    Fugitive *fugitive = [items objectAtIndex:indexPath.row];
    cell.textLabel.text = fugitive.name;

    return cell;
}

The problem is that this shows up nothing in the view controller, no errors as well. I have connected the required outlets in the tabbar controller.

Checking in debugger, the mutable array shows 0 objects. I've just started with iOS development. Can somebody help me in figuring out what can be going wrong here?

UPDATE - With the help of Yuji's comment, I checked the file being copied in the Documents folder of iPhone Simulator. It does not have any data. That is why the view is showing no data. The problem thus seems to be in the code I am using to copy the file from project's folder to the application's documents folder.

Here is how it goes....

// MyAppDelegate.m
#import "MyAppDelegate.h"

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    

    // Override point for customization after application launch.
    [self createEditableCopyOfDatabaseIfNeeded];

    [self.window addSubview:tabcontroller.view];
    [self.window makeKeyAndVisible];

    return YES;
}

- (void)createEditableCopyOfDatabaseIfNeeded {
    NSString *defaultDirectory = [[self applicationDocumentsDirectory] absoluteString];
    NSString *writableDBPath = [defaultDirectory stringByAppendingPathComponent:@"iBountyHunder1.sqlite"];

    NSFileManager *fileManager = [NSFileManager defaultManager];
    if (![fileManager fileExistsAtPath:writableDBPath]) {
        NSString *defaultDBPath = [[NSBundle mainBundle] pathForResource:@"iBountyHunder" ofType:@"sqlite"];
        if (defaultDBPath) {
            NSError *error;
            BOOL success = [fileManager copyItemAtPath:defaultDBPath toPath:writableDBPath error:&error];
            if (!success) {
                NSLog(@"The error is %@", [error localizedDescription]);
            }
        }
    }
}

Can't get why this isn't working????

Upvotes: 0

Views: 990

Answers (5)

ucupsz
ucupsz

Reputation: 11

I got the same error when trying to follow the code from the book. Having checked the available database on the writeable path, and checked the content of both .sqlite files, I've found that the name of the database should match with the project name. Looking at your import statement, it looks like you name your project as My. So the database should be copied with My.sqlite as the file's name. I've tried it on my macbook, and it works.

FYI, I use sqlite database browser to check the content of .sqlite files.

Upvotes: 1

TonyMac
TonyMac

Reputation: 11

I've just noticed that you have named your db "iBountyHunder" as well as "iBountyHunder1" in one of the code snippets above. The file supplied by Head First is "iBountyHunter" (t, not d at the end).

You might want to check that your project name is consistent with your db file name because the core data template expects them to be identical.

When I was getting the db working, I also found it helped every time to use Build -> Clean All Targets as well as iPhoneSimulator -> Reset Contents and Settings...

Upvotes: 1

Kenny K.
Kenny K.

Reputation: 36

Did you copy the sqlite3 file to the Documents directory by yourself? The code creates writable database copy to Documents directory if it can't find one there.

Do the following.

  1. Run the project in Xcode
  2. Press home button on the iPhone Simulator
  3. Remove iBountyHunter
  4. Quit Simulator
  5. Run the project again

Upvotes: 1

Evan
Evan

Reputation: 6161

I downloaded the code sample for Chapter 7. I opened it in XCode and updated the Project->Edit Project Settings->Base SDK to the latest sdk (4.2). If the plan was to create a new project from scratch be sure that it is backed by Core Data and that the code from their project is copied and pasted correctly.

Upvotes: 0

WoodenKitty
WoodenKitty

Reputation: 6529

Your class begins with #import "MyAppDelegate.h", which makes me suspect it's your app delegate and not a view controller. If it's not a view controller then I don't think - (void)viewWillAppear:(BOOL)animated will get run. Try putting a NSLog(@"this code is being run"); in that method to see if it's being executed.

Upvotes: 0

Related Questions