SQLite resets when Project is Re-ran in Simulator

Discussion in 'iOS Programming' started by mcnuggets, Jan 7, 2012.

  1. mcnuggets macrumors newbie

    Joined:
    Jan 2, 2009
    #1
    I downloaded the source code located here on how to do a simple "To Do List":

    iPhone Programming Tutorial ? Creating a ToDo List Using SQLite Part 4 | iPhone Programming Tutorials

    What I notice is when I add anything to the list and then re-ran the simulator... whatever I added is not saved.

    I installed the app on my phone and notice that the database is reseted when the Phone is turned off. The app works fine... but when the Phone is turned off (hold power button for 5 seconds) and when it turns back on... whatever I added to the To Do list is gone.

    I spent several days on this and can't figure it out why it keeps getting deleted after phone is turned off. Source Code is here:
    http://staging.icodeblog.com/wp-content/uploads/2008/09/todo-part-41.zip
     
  2. ChristianVirtual, Jan 7, 2012
    Last edited: Jan 8, 2012

    ChristianVirtual macrumors 601

    ChristianVirtual

    Joined:
    May 10, 2010
    Location:
    日本
    #2
    Didn't have the chance to check you source but my guess is you
    a) try to write a DB in your bundle
    b) recreate the DB when you restart your app

    Make sure you create the DB only in your document folder or when using iCloud where the system tell you to do so. Check if the DB file is already there and just open it in that case. You can use the DB in your bundle as template but should create a working instance.

    One more hint: sometimes the folder where the simulator place the binary is changing. Didn't myself yet fully understood under what conditions. But on the device that's not an issue.
     
  3. mcnuggets thread starter macrumors newbie

    Joined:
    Jan 2, 2009
    #3
    The database opens without a problem. And it writes to it without any issues. But when the phone is turned off... it wipes out whatever entry I wrote in there. It's as if I'm writing to the database temporarily. The database is stored locally and not in the cloud.
     
  4. PhoneyDeveloper macrumors 68040

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #4
    Can you print out the path to your db file? Does the app come with a prebuilt db file or does it create a new one?
     
  5. mcnuggets thread starter macrumors newbie

    Joined:
    Jan 2, 2009
    #5
    The app comes with a prebuilt db that it edits. What I don't get is... it works... it's able to edit the database and add more info. It's just when the phone is turned off (loses power)... that's when it loses the data.

    The source code comes with a todo.sqlite file. It's in the root directory where the project is located. On xcode I placed it under the "Resource" folder.

    This is the code in the AppDelegate.m file:

    - (void)createEditableCopyOfDatabaseIfNeeded {
    BOOL success;
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSError *error;
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:mad:"todo.sqlite"];
    success = [fileManager fileExistsAtPath:writableDBPath];
    if (success) return;
    NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:mad:"todo.sqlite"];
    success = [fileManager copyItemAtPath:defaultDBPath toPath:writableDBPath error:&error];
    if (!success) {
    NSAssert1(0, @"Failed to create writable database file with message '%@'.", [error localizedDescription]);
    }
    }


    By the way thanks for the people helping me out on this. It's driving me nuts all week now.
     
  6. admanimal macrumors 68040

    Joined:
    Apr 22, 2005
    #6
    Are you absolutely sure that it only happens if the device is turned off? What if you kill the app from the task list and then re-run it?

    Can you show us the code that calls createEditableCopyOfDatabaseIfNeeded (I'm guessing it's applicationDidFinishLaunching)?
     
  7. mcnuggets thread starter macrumors newbie

    Joined:
    Jan 2, 2009
    #7
    You're absolutely right. When you kill the app from the task list... all the data is gone. So basically it seem it's just temporarily writing to the database in memory.

    I put the entire code of createEditableCopyofDabaseIFNeeded in my previous code. Please let me know if I'm missing anything.

    Here's the code for applicationDidFinishLaunching:

    - (void)applicationDidFinishLaunching:(UIApplication *)application {

    [self createEditableCopyOfDatabaseIfNeeded];
    [self initializeDatabase];

    // Configure and show the window
    [window addSubview:[navigationController view]];
    [window makeKeyAndVisible];
    }
     
  8. admanimal macrumors 68040

    Joined:
    Apr 22, 2005
    #8
    It doesn't look like you're doing anything wrong in terms of creating the database if necessary. My guess is that you're not actually committing anything to the database, but rather just storing items in whatever data structures are in your program. Take a look at your SQL statements and make sure they are executing correctly.
     
  9. RonC macrumors regular

    Joined:
    Oct 18, 2007
    Location:
    Chicago-area
    #9
    You should have some code that looks roughly like this:
    Code:
    +(BOOL)commitChangesInContext:(NSManagedObjectContext *)context
    {
        NSError *error = nil;
        
        if (![context save:&error]) {
            NSLog(@"Context save error: %@", error);
            abort();
        }
        
        return !error;
    }
    
    If you can't find save: run on a NSManagedObjectContext, then you ain't saving jack.
     
  10. admanimal macrumors 68040

    Joined:
    Apr 22, 2005
    #10
    He's using plain SQLite, not Core Data, so there won't be any NSManagedObjectContext.
     
  11. mcnuggets thread starter macrumors newbie

    Joined:
    Jan 2, 2009
    #11
    Someone suggested that I was calling initializeDatabase everytime the app loads but if I comment that out on applicationDidFinishLaunching... my app crashes.

    - (void)initializeDatabase {
    NSMutableArray *todoArray = [[NSMutableArray alloc] init];
    self.todos = todoArray;
    [todoArray release];
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *path = [documentsDirectory stringByAppendingPathComponent:mad:"todo.sqlite"];
    // Open the database. The database was prepared outside the application.
    if (sqlite3_open([path UTF8String], &database) == SQLITE_OK) {
    // Get the primary key for all books.
    const char *sql = "SELECT pk FROM todo";
    sqlite3_stmt *statement;
    if (sqlite3_prepare_v2(database, sql, -1, &statement, NULL) == SQLITE_OK) {
    while (sqlite3_step(statement) == SQLITE_ROW) {
    int primaryKey = sqlite3_column_int(statement, 0);
    Todo *td = [[Todo alloc] initWithPrimaryKey:primaryKey database:database];

    [todos addObject:td];
    [td release];
    }
    }
    sqlite3_finalize(statement);
    } else {
    sqlite3_close(database);
    NSAssert1(0, @"Failed to open database with message '%s'.", sqlite3_errmsg(database));
    // Additional error handling, as appropriate...
    }

    }


    But here's something I found out. When re-running the simulator, ending the task, or turning off the phone... the entries I add or delete will update the database (or list). It's just the entries will have blank values. Maybe I am trying to reopen the original database?
     
  12. phantax macrumors member

    Joined:
    Feb 2, 2009
    #12
    Are you sure you are actually writing the data to the database? Have you tried actually reading it back out after a write and see if the values are not null.

    My thought is that you are just updating your data source, whatever that may be, and not actually writing valid values to the database at the same time.
     
  13. admanimal macrumors 68040

    Joined:
    Apr 22, 2005
    #13
    You need to call initializeDatabase because that is the code that actually opens the database file for use. Can you show us the code where you actually insert or update things in the database?
     

Share This Page