简体   繁体   English

无法将sqlite数据库从app的mainbundle复制到用户文档

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

I can't copy my sqlite database to the users documents folder, the database has always 0 byte but should have 322 kb. 我无法将我的sqlite数据库复制到用户文档文件夹,数据库总是0字节但应该有322 kb。

I have also checked that the database is included in the target membership. 我还检查了数据库是否包含在目标成员中。

The Problem is that i can't copy the database correctly. 问题是我无法正确复制数据库。

Here is my code: 这是我的代码:

-(void)initDatabase
{
// Create a string containing the full path to the sqlite.db inside the documents folder
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *databasePath = [documentsDirectory stringByAppendingPathComponent:@"wine.sqlite"];

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

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

    // 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"];
        //NSString *databasePathFromApp = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"wine.sqlite"];

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

        NSLog(@"Database created");
    }
}

} }

There is a logic error, you check for databaseAlreadyExists inside the 有一个逻辑错误,你在里面检查databaseAlreadyExists

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)
{
   ...
}

you open a DB (making a new 0 byte one if it isnt there using sqlite3_open and THEN copy the shipped one right where the new DB should be.. 你打开一个数据库(如果不是那里使用sqlite3_open那么新的0字节一个,然后复制出来的那个新数据库应该在哪里..

  • you check if DB_docs is there 你检查DB_docs是否存在
  • but then you open DB_docs with sqlite no matter what 但无论如何你用sqlite打开DB_docs
  • and THEN you try copy it from the bundle into the OPENED File path 然后,您尝试将其从捆绑包复制到OPENED文件路径

-(void)initDatabase
{
    // Create a string containing the full path to the sqlite.db inside the documents folder
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *databasePath = [documentsDirectory stringByAppendingPathComponent:@"wine.sqlite"];

    // 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)
    {
        NSLog(@"db opened");
    }
}

I just use the following method written in AppDelegate, (It seems like the method body is huge, but it's actually not. Just remove all the comments and see for the clarity after you read the comments): 我只是使用在AppDelegate中编写的以下方法,(看起来方法体很大,但实际上并非如此。只需删除所有注释,并在阅读注释后查看清晰度):

#pragma mark - SQLite DB
// SQLite Copy the Database.
-( void ) checkAndCreateDatabase
{
// Check if the SQL database has already been saved to the users phone, if not then copy it over
BOOL success;

NSString *databasePath = [LIBRARY_DIR_PATH stringByAppendingPathComponent:DATABASE_NAME];
NSLog(@"%@",databasePath);

// Create a FileManager object, we will use this to check the status
// of the database and to copy it over if required
NSFileManager *fileManager = [NSFileManager defaultManager];

// Check if the database has already been created in the users filesystem
success = [fileManager fileExistsAtPath:databasePath];
// If the database already exists then return without doing anything
if(success) return;

NSLog(@"DB WASN'T THERE! SO GONNA COPY IT!");

// If not then proceed to copy the database from the application to the users filesystem
// Get the path to the database in the application package
NSString *databasePathFromApp = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:DATABASE_NAME];
success = [fileManager fileExistsAtPath:databasePathFromApp];
if (success) {
    NSLog(@"SIMULATOR FOUND DB FROM APP, GONNA COPY IT");
} else {
    NSLog(@"SIMULATOR COULDN'T FIND DB\nIT SHOULD BE IN : %@\nPlease check if you have added the DB file and selected its target", databasePathFromApp);
}

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

} }

And call that method within 并在内部调用该方法

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

As follows: 如下:

//Copy the SQLite3 DB File
[self checkAndCreateDatabase];

Hint: Keep in mind that you need to add the SQLite DB file to your correct target membership when you drag and drop the db file to the XCode Project. 提示:请记住,在将db文件拖放到XCode项目时,需要将SQLite DB文件添加到正确的目标成员资格中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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