35

When I initially create an SQLite database file with pre-inserted datasets for my application, I would have to place this file somewhere in my Xcode project so that it goes to my iPhone application. I guess "ressources" is the right place for that.

What are the basic "steps" for deployment of an SQLite database file in an iPhone application?

  • creating the database manually
  • adding the database file to the project (where?)

I'm currently reading the whole SQLite documentation, although that's not much iPhone related.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Thanks
  • 40,109
  • 71
  • 208
  • 322

2 Answers2

70

You need to add the SQLite file to your Xcode project first - the most appropriate place is in the resources folder.

Then in your application delegate code file, in the appDidFinishLaunching method, you need to first check if a writable copy of the the SQLite file has already been created - ie: a copy of the SQLite file has been created in the users document folder on the iPhone's file system. If yes, you don't do anything (else you would overwrite it with the default Xcode SQLite copy)

If no, then you copy the SQLite file there - to make it writable.

See the below code example to do this: this has been taken from Apple's SQLite books code sample where this method is called from the application delegates appDidFinishLaunching method.

// Creates a writable copy of the bundled default database in the application Documents directory.
- (void)createEditableCopyOfDatabaseIfNeeded {
    // First, test for existence.
    BOOL success;
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSError *error;
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:@"bookdb.sql"];
    success = [fileManager fileExistsAtPath:writableDBPath];
    if (success)
        return;
    // The writable database does not exist, so copy the default to the appropriate location.
    NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"bookdb.sql"];
    success = [fileManager copyItemAtPath:defaultDBPath toPath:writableDBPath error:&error];
    if (!success) {
        NSAssert1(0, @"Failed to create writable database file with message '%@'.", [error localizedDescription]);
    }
}

============

Here's the above code in Swift 2.0+

// Creates a writable copy of the bundled default database in the application Documents directory.
private func createEditableCopyOfDatabaseIfNeeded() -> Void
{
    // First, test for existence.
    let fileManager: NSFileManager = NSFileManager.defaultManager();
    let paths:NSArray = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
    let documentsDirectory:NSString = paths.objectAtIndex(0) as! NSString;
    let writableDBPath:String = documentsDirectory.stringByAppendingPathComponent("bookdb.sql");

    if (fileManager.fileExistsAtPath(writableDBPath) == true)
    {
        return
    }
    else // The writable database does not exist, so copy the default to the appropriate location.
    {
        let defaultDBPath = NSBundle.mainBundle().pathForResource("bookdb", ofType: "sql")!

        do
        {
            try fileManager.copyItemAtPath(defaultDBPath, toPath: writableDBPath)
        }
        catch let unknownError
        {
            print("Failed to create writable database file with unknown error: \(unknownError)")
        }
    }
}
Nikolay Suvandzhiev
  • 8,465
  • 6
  • 41
  • 47
Raj
  • 6,810
  • 6
  • 48
  • 56
  • Where should be the database if you want to write on it? I know that if it is in Resourses group (Main Bundle) it is read-only, so which is the right way to allow both, writing and reading? Thanks! –  Jan 11 '11 at 16:04
  • I know this is a little late, but how would I go about finding if it needs updating from the main bundle? I tried checking the file attributes, but the modification date of the file in the app changes whenever I compile a new version. – Flipper Feb 08 '12 at 20:52
  • I have open the database file in one of my view controller where I insert values in my table , and again opens it in another view controller where I retrieve the values here I am getting Unknown error. Is it creating another instances of my database? – anjum Apr 17 '12 at 07:02
  • 1
    Why your database name have .sql extension? – Paweł Brewczynski Jul 28 '14 at 12:20
6

If you're just going to be querying for data, you should be able to leave it in the main bundle.

This, however, is probably not a good practice. If you were to extend your application in the future to allow for database writing, you'd have to figure everything out again...

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Willi Ballenthin
  • 6,444
  • 6
  • 38
  • 52
  • 3
    @ Willi Not necessarily true. If he were to extend his app in the future, he could always just add the above functionality in an update. Should work seamlessly. –  Jan 11 '11 at 16:03