【问题标题】:Unable to copy database over无法复制数据库
【发布时间】:2012-03-14 15:18:41
【问题描述】:

我的目标是 iOS 5.1,并尝试将数据库从我的应用程序文件复制到我的 Documents 文件夹。我过去曾在应用程序上使用相同的代码完成此操作,所以我有点困惑为什么这次它不起作用。

这是我用来检查它是否存在并在不存在时复制它的方法。来自here

-(void) checkAndCreateDatabase{
// Check if the SQL database has already been saved to the users phone, if not then copy it over
BOOL success;

// 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:self.databasePath];

// If the database already exists then return without doing anything
if(success) return;

NSLog(@"Installing db: %@", self.databasePath);
// 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:databaseName];

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

//[databasePathFromApp release];
//[fileManager release];

}

当我尝试查询数据库时,我会这样做:

sqlite3 *database1; 

// Open the database from the users filessytem
if(sqlite3_open([self.databasePath UTF8String], &database1) == SQLITE_OK) {
    // Setup the SQL Statement and compile it for faster access

    NSString *sqlStatement = [NSString stringWithFormat: @"update login set is_logged=0"];
    sqlite3_stmt *compiledStatement;

    if(sqlite3_prepare_v2(database1, [sqlStatement UTF8String], -1, &compiledStatement, NULL) == SQLITE_OK) {

        if(SQLITE_DONE != sqlite3_step(compiledStatement)){
            NSAssert1(0, @"Error while updating logged. '%s'", sqlite3_errmsg(database1));
            NSLog(@"Error setting logged_in to 0: %s", sqlite3_errmsg(database1));
        }
        else{
            NSLog(@"Made Logged_in=0");
        }
    }
    else{
        NSLog(@"Prop problem1: %s", sqlite3_errmsg(database1));
        NSLog(@"Couldn't prep 1");
    }
    // Release the compiled statement from memory
    sqlite3_finalize(compiledStatement);
}
else{

    NSLog(@"Couldn't even open db1");
}
sqlite3_close(database1);

sqlite3_open() 函数在这种情况下返回 false,sqlite3_errmsgno such table: login

我有一个每秒调用一次的函数,它创建一个使用该数据库对象的对象。会不会是数据库在那一秒内没有被复制,下一个调用中断了之前的复制?这听起来不太可能。

任何想法可能是什么问题?

解决方案 我咨询了这个问题:here,根据第 2 点,我的数据库似乎不在“复制捆绑资源”列表中。我添加了它,现在一切似乎都很好。

感谢你们让我朝着正确的方向思考。

【问题讨论】:

  • 使用管理器从手机下载文件,看看复制了什么。 (另外,请注意,您可能需要将 DB 文件标记为“不备份”以通过 Apple 的新 5.1 标准。)
  • 它显示在 Documents 文件夹中,但内容为空白。我会假设这与 sql 文件的编码问题有关?
  • 从头开始,我刚刚删除了应用程序并重新安装,并且数据库不在 Documents 文件夹中。似乎 [empty] 数据库文件只有在我尝试查询后才会出现。
  • 是的,如果没有,Sqlite 会创建一个文件。仔细检查您是否从正确的位置复制,等等。

标签: iphone ios xcode ios5.1


【解决方案1】:

尝试验证复制过程的每个阶段是否返回有效对象。可能是(例如)您在搜索资源路径时没有包含扩展名。我倾向于使用 NSBundle pathForResource:ofType 函数从包中获取内容。此外,对于空数据库,如果数据库不存在,sqlite 的 open 函数会创建一个数据库,然后打开它。尝试从copyItemAtPath获取错误

【讨论】:

  • 错误是:Error Domain=NSCocoaErrorDomain Code=260 “操作无法完成。(Cocoa 错误 260。)” UserInfo=0x271dd0 {NSFilePath=/var/mobile/Applications/F39FFDFB- 32FB-4533-8EE2-5ECA8A7FBF60/MyApp.app/myappdb.sql, NSUnderlyingError=0x271d30“操作无法完成。没有这样的文件或目录”}
  • 当我使用 [[NSBundle mainBundle] pathForResource:@"myappdb" ofType:@"sql"] 我收到此错误 - 由于未捕获的异常 'NSInvalidArgumentException' 导致应用程序终止,原因:'*** -[NSFileManager copyItemAtPath:toPath:error:]: 源路径为 nil'
  • 所以在我看来,我的问题是我用来获取资源文件夹中原始数据库的路径...
  • 啊,数据库好像不在“Copy bundel Resources”列表中。我添加了它,现在一切似乎都很好。奇怪的是它没有自动添加。
  • @emachine :- 添加您的评论作为问题的答案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-18
  • 1970-01-01
  • 2020-05-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多