How to Copy SQLite Database When Application Is Launched in iOS

how to copy/put Sqlite Database file to Device to test app on it - Xcode

Include the Sqlite DB file into your project, and copy it into Documents folder if not exist when the app access the DB file.

#define DB_NAME @"XXX.sqlite"
#define DB_FULLPATH [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:DB_NAME]

+ (void)createDatabase
{
NSFileManager *fileManager = [NSFileManager defaultManager];
if(![fileManager fileExistsAtPath:DB_FULLPATH]) {
NSString *bundlePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:DB_NAME];
[fileManager copyItemAtPath:bundlePath toPath:DB_FULLPATH error:nil];
}

}

How to get Sqlite database file when application is running on device?

I use this method for getting the URL to a database:

+ (NSURL *)storeURL
{
if ([self isExecutingUnitTests])
{
NSString *directory = [[NSFileManager defaultManager] currentDirectoryPath];
return [NSURL fileURLWithPath:[directory stringByAppendingPathComponent:@"UnitTests/test-database.sqlite"]];
}
else
{
return [NSURL fileURLWithPath:[NSHomeDirectory() stringByAppendingPathComponent:@"Documents/database.sqlite"]];
}
}

It works fine on the simulator, on the device and even when executing unit tests!
UnitTests and Documents should both exist on the level of the .xcodeproj.

Cannot copy sqlite file into bundle/app, resource for iPhone

NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex:0];

NSString *dbPath = [documentsDir stringByAppendingPathComponent:@"moviedbl.data"];

if([fileManager fileExistsAtPath:dbPath]==NO){

NSString *defaultDBPath = [[NSBundle mainBundle] pathForResource:@"moviedbl" ofType: @"data"];
BOOL success = [fileManager copyItemAtPath:defaultDBPath toPath:dbPath error:&error];

if(!success){
NSAssert1(0, @"Failed to create writable database file with message '%'.", [error localizedDescription]);
}
}

Can't copy sqlite database from app's mainbundle to users documents

There is a logic error, you check for databaseAlreadyExists inside the

if (sqlite3_open([databasePath UTF8String], &databaseHandle) == SQLITE_OK) { ... }

block.

What you probably meant is

// Check to see if the database file already exists
bool databaseAlreadyExists = [[NSFileManager defaultManager] fileExistsAtPath:databasePath];

// Create the database if it doesn't yet exists in the file system
if (!databaseAlreadyExists)
{
// Get the path to the database in the application package
NSString *databasePathFromApp = [[NSBundle mainBundle] pathForResource:@"wine" ofType:@"sqlite"];

// Copy the database from the package to the users filesystem
[[NSFileManager defaultManager] copyItemAtPath:databasePathFromApp toPath:databasePath error:nil];

NSLog(@"Database created");
}

// Open the database and store the handle as a data member
if (sqlite3_open([databasePath UTF8String], &databaseHandle) == SQLITE_OK)
{
...
}

Sqlite database file managing in Swift 3 and iOS (copy from local and/or bundle to app)

With @Rob's help, I came to following solution which satisfied my requirement. Previously it was necessary to add sqlite file into xcode project, with proper target.

func prepareDatabaseFile() -> String {
let fileName: String = "foo.sqlite"

let fileManager:FileManager = FileManager.default
let directory = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first!

let documentUrl= directory.appendingPathComponent(fileName)
let bundleUrl = Bundle.main.resourceURL?.appendingPathComponent(fileName)

// here check if file already exists on simulator
if fileManager.fileExists(atPath: (documentUrl.path)) {
print("document file exists!")
return documentUrl.path
else if fileManager.fileExists(atPath: (bundleUrl?.path)!) {
print("document file does not exist, copy from bundle!")
fileManager.copyItem(at:bundleUrl, to:documentUrl)
}

return documentUrl.path
}

Where would you place your SQLite database file in an iPhone app?

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)")
}
}
}

iOS: How to copy pre-seeded database at the first running app with SQLite.swift to writeable location?

how do I prevent the database from being replaced?

Check the destination before you copy the database. If there's already a file there, don't do the copy. You can use -[NSFileManager fileExistsAtPath:] to check for an existing file.



Related Topics



Leave a reply



Submit