简体   繁体   中英

What is the best way to write a previously created Sqlite database to documents in iOS

I have a previously created Sqlite database file that I am bundling with an iOS application. My question is what is the best way to write this data to the phone so that I may alter the tables from the application there on?

My research indicates that I may need to loop through the entire .sql file and insert/create the necessary tables and values on the phone manually.

Is there no way to just write the database to internal storage and then manipulate it from then on?

You can add it to your supporting files in the project and then copy the file as a template db if it doesn't exist and then open it. Once you open it you can do what you want with it.

Here's some sample code from a sample project I had that does this. In my sample it's a contact database. Notice how ensurePrepared will copy it from the bundle if it doesn't exist. I copy to library path but you can copy to documents path.

- (BOOL)ensureDatabaseOpen: (NSError **)error
{
    // already created db connection
    if (_contactDb != nil)
    {
        return YES;
    }

    NSLog(@">> ContactManager::ensureDatabaseOpen");    
    if (![self ensureDatabasePrepared:error])
    {
        return NO;
    }

    const char *dbpath = [_dbPath UTF8String]; 
    if (sqlite3_open(dbpath, &_contactDb) != SQLITE_OK &&
        error != nil)
    {
        *error = [[[NSError alloc] initWithDomain:@"ContactsManager" code:1000 userInfo:nil] autorelease];
        return NO;
    }

    NSLog(@"opened");

    return YES;
}

- (BOOL)ensureDatabasePrepared: (NSError **)error
{
    // already prepared
    if ((_dbPath != nil) &&
        ([[NSFileManager defaultManager] fileExistsAtPath:_dbPath]))
    {
        return YES;
    }

    // db in main bundle - cant edit.  copy to library if !exist
    NSString *dbTemplatePath = [[NSBundle mainBundle] pathForResource:@"contacts" ofType:@"db"];
    NSLog(@"%@", dbTemplatePath);

    NSString *libraryPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) lastObject];
    _dbPath = [libraryPath stringByAppendingPathComponent:@"contacts.db"];

    NSLog(@"dbPath: %@", _dbPath);

    // copy db from template to library
    if (![[NSFileManager defaultManager] fileExistsAtPath:_dbPath])
    {
        NSLog(@"db not exists");
        NSError *error = nil;
        if (![[NSFileManager defaultManager] copyItemAtPath:dbTemplatePath toPath:_dbPath error:&error])
        {
            return NO;
        }

        NSLog(@"copied");
    }    

    return YES;    
}

Store the database in the bundle (in the project). In the App Delegate copy the database to the Documents directory (only do this if the database file doesn't already exist in the documents directory otherwise you will always be overwriting your file). In your code always reference the copy in the Document's directory.
Also read this SO Question for some code on how to do the copy.

Voila.

Include the .sql file in your resource folder of the project and copy it into user's document folder on the first launch of your application(or if the file is not found). You can use NSFileManager for this.

Take a look at Where would you place your SQLite database file in an iPhone app?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM