【问题标题】:Unable to connect SQLite Database in iOS无法在 iOS 中连接 SQLite 数据库
【发布时间】:2012-07-24 17:30:27
【问题描述】:

我对 SQLite 和 iOS 完全陌生。我正在关注如何在 iOS 中使用 SQLite 的基本教程:

http://www.switchonthecode.com/tutorials/using-sqlite-on-the-iphone#comment-11617

在上面的链接中,他们将数据库指定为:

sqlite3 *database;

int result = sqlite3_open("/myExampleDatabase.db", &database);

但是当我使用上面的代码替换我的数据库名称时,我得到一个错误,如后续警报视图中指定的那样。

我的问题是,我必须将数据库文件添加到我的资源文件夹中吗?如果没有,我是否必须将我的数据库文件放在 iOS 可以访问的地方?

【问题讨论】:

  • 另外,如果有人能给我提供一些关于将 SQLite 与 iOS 连接的很好的教程链接,那就太好了?再次感谢。
  • 如果您事先创建了数据库,您需要确保它包含在您的捆绑包中,您可能还希望将它从捆绑包复制到您的 Documents 文件夹(即查看它是否已经在那里,如果没有,请将其从您的捆绑包复制到文档等)。然后,您的 sqlite3_open 调用必须引用结果文件的完全指定路径。有关新 SQLite 用户的其他一些提示,请参阅stackoverflow.com/questions/11605072/…
  • 谢谢罗伯特!我已经在我的包中添加了数据库,并对我的 Documents 文件夹做了同样的事情,但我仍然无法弄清楚。也许,我错过了一些东西。将进一步挖掘..再次感谢..

标签: ios sqlite


【解决方案1】:

我建议为 SQLite 使用 FMDB 包装器: https://github.com/ccgus/fmdb

【讨论】:

  • 感谢 Seb。我会试一试:)
  • +1 我同意这一点。 FMDB 真的让你摆脱了 sqlite 调用的细节。它不会解决查找数据库的问题,但总体而言它是一个福音,消除了自己调用 sqlite 的所有复杂性。
【解决方案2】:

如果你想打开一个 sqlite 数据库,你可能想:

  1. 确保将数据库包含在包中。

  2. 以编程方式将数据库从您的包复制到您的文档(如果用户要修改数据库,这尤其重要;如果您只是阅读,您可以继续打开包中的版本)。

  3. 如果您在模拟器中运行此程序,您可以继续检查捆绑包和文档文件夹(如果事情不正常),以确保一切都在应有的位置。您的模拟器文件夹类似于“~/Library/Application Support/iPhone Simulator/5.1/Applications/”(将 5.1 替换为您正在使用的模拟器的任何版本)。您可能需要通过在Terminal 命令行窗口中运行chflags nohidden ~/Library 来取消隐藏您的Library 文件夹。

因此,获取数据库路径的代码(如果还没有,则将其复制到 Documents)可能如下所示:

NSString *databaseName = kDatabaseName; // obviously, replace this with your database filename, e.g., @"myExampleDatabase.db"

NSString *documentsFolder          = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *databaseFullDocumentPath = [documentsFolder stringByAppendingPathComponent:databaseName];
NSString *databaseFullBundlePath   = [[NSBundle mainBundle] pathForResource:databaseName ofType:@""];

NSFileManager *fileManager = [NSFileManager defaultManager];
if (![fileManager fileExistsAtPath:databaseFullDocumentPath])
{
    NSAssert([fileManager fileExistsAtPath:databaseFullBundlePath], @"Database not found in bundle");

    NSError *error;
    if (![fileManager copyItemAtPath:databaseFullBundlePath toPath:databaseFullDocumentPath error:&error])
        NSLog(@"Unable to copy database from '%@' to '%@': error = %@", databaseFullBundlePath, databaseFullDocumentPath, error);
}

然后,如果你在做自己的 sqlite 调用,它会是这样的:

sqlite3 *database;
if (sqlite3_open_v2([databaseFullDocumentPath UTF8String], &database, SQLITE_OPEN_READWRITE, NULL) == SQLITE_OK)
{

    // do whatever you want to do
}

或者,或者,如果您使用的是 FMDB,它会是这样的:

FMDatabase *db = [[FMDatabase alloc] initWithPath:databaseFullDocumentPath];
NSAssert(db, @"Unable to open create FMDatabase");
BOOL success = [db open];
NSAssert(success, @"Unable to open database");
if (success)
{
    // do whatever you want to do
}

【讨论】:

  • 好吧,我终于用 FMDB 成功了!确实很简单……谢谢大家! +1
【解决方案3】:

但是,在大多数情况下,我完全支持前面的答案:

您确定必须使用sqlite3 而不是Core Data

有几个讨论可以让您了解何时使用数据库包装器(如fmdb)以及何时使用Core Data。 (就我个人而言,我喜欢使用 fmdb,但它总是会导致更多的代码、复杂性,并且大多数时候性能更差)

一些开始使用Core Data的链接:

【讨论】:

  • 好问题。如果只做 iOS 而不做复杂的 SQL,那么 Core Data 是一个很好的技术,有一些真正的优势。但是,如果将 FMDB 用于您的 sqlite 内容,则非常简单和容易。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-22
  • 2018-04-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多