【问题标题】:SQLite database not loading on iphone deviceSQLite 数据库未在 iPhone 设备上加载
【发布时间】:2014-08-25 02:41:29
【问题描述】:

当我在模拟器上测试我的应用程序时,一切正常。但是当我在 iPhone 上测试应用程序时,它不会从 db.sqlite3 数据库加载。

我尝试了互联网上的所有解决方案。我清理了应用程序。我将数据库添加到构建短语中 - 复制捆绑资源等。 你能帮助我吗?我的编码有任何失败吗?

-(void)openDataBase{

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    dbPath = [documentsDirectory stringByAppendingString:@"db.sqlite3"];

    //load it
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSString *pathInRessource = [[NSBundle mainBundle] pathForResource:@"db" ofType:@"sqlite3"];

    //exist it?
    if (![fileManager fileExistsAtPath:dbPath]) {
        [fileManager copyItemAtPath:pathInRessource toPath:dbPath error:nil];
    }

    //open database
    int result = sqlite3_open([dbPath UTF8String], &db);
    if (result != SQLITE_OK) {
        sqlite3_close(db);

        return;
    }

    //if ok
    NSLog(@"Data base opened");

}

【问题讨论】:

  • 好吧,你有一堆代码。当你走过它时,你什么时候注意到有什么不对劲的地方?您忽略了哪些错误消息?
  • 嘿,在模拟器上我收到消息“数据库已打开”,但是当我在 iphone 上运行它时,我没有收到任何消息。我想,iphone找不到路径。但我不知道如何解决。
  • 我会专门查看sqlite3_open() 返回的内容,并对照sqlite.org/c3ref/c_abort.html 进行检查
  • 我的猜测是你得到了错误的路径(这可以解释为什么它在模拟器中工作,它是不同的),它应该看起来像file:///var/mobile/Applications/...id.../Documents/YourDatabase.sqlite。尝试复制代码以从其他来源查找路径。
  • According to the docs 它返回一个BOOL,而不是一个字符串。您可能也不应该像使用 nil 那样吞下错误

标签: iphone xcode sqlite ios-simulator


【解决方案1】:

在打开数据库时,您可以使用 else 情况调用它来解决问题。

if (sqlite3_open([getDBPath UTF8String], &sqlhandle) == SQLITE_OK)
{
     NSLog(@"Database Open!");
}
else
{
    NSLog(@"Select err: %s",sqlite3_errmsg(sqlhandle));
}

您将能够使用此获得正确的错误消息

【讨论】:

  • 现在我用 iOS 模拟器和我的设备进行了调试。然后我比较了结果。唯一不同的是我的整数结果。在模拟器上结果 = 0。在设备上 = 4。在 iOS 模拟器上,它从 if 语句转到 NSLog。在设备上,它从 if 到关闭并返回。我暂时不明白。
【解决方案2】:

我不知道你在哪里卡住了,我正在做同样的事情并且它对我来说工作正常。

顺便说一句,我已经更新了你的代码,我是如何处理的,请检查让我知道如果发现和麻烦。

//My DB variable
static sqlite3 *database;

-(void)openDataBase{
if (database == NULL) 

    sqlite3 *mDatabse;

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    dbPath = [documentsDirectory stringByAppendingString:@"db.sqlite3"];

    //load it
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSString *pathInRessource = [[NSBundle mainBundle] pathForResource:@"db" ofType:@"sqlite3"];

    //exist it?
    if (![fileManager fileExistsAtPath:dbPath]) {
        [fileManager copyItemAtPath:pathInRessource toPath:dbPath error:nil];
    }

    if (sqlite3_open([path UTF8String], &mDatabse) == SQLITE_OK) {   
            NSLog(@"Database Successfully Opened");
            database = mDatabse;


        } else {
            NSLog(@"Error in opening database");
            mDatabse = NULL;
        }

}

【讨论】:

  • 当您说“我的类变量”时,您实际上是指实例变量吗?
  • 是的,您可以在头文件或实现文件中声明它。抱歉,如果让您感到困惑,我刚刚更新了
  • 好吧,我没有感到困惑,但是使用类变量还是实例变量会影响可以同时使用的该类的实例数。你似乎做了更糟糕的选择。
  • 我同意类和实例变量的影响,但是我用这个变量检查​​数据库然后我有一个局部变量,我做数据库操作,仍然如果你发现它可以改进,我会欢迎的。
  • 这很简单;使其成为类的私有类别中的实例变量:@implementation Database () { sqlite3 *_database; } ... @implementation Database { ... }。这允许此类的多个实例存在,这可能非常有用。
猜你喜欢
  • 2011-10-19
  • 1970-01-01
  • 1970-01-01
  • 2012-05-09
  • 1970-01-01
  • 2012-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多